Skip to content

Commit 54f6307

Browse files
authored
[example] cel-shading and outline using inverted hull (#5615)
* added cel-shading and outline using inverted hull example * new screenshot * added glsl100+120 compat * updated view * unnecessary spacing
1 parent 3e926d6 commit 54f6307

File tree

14 files changed

+562
-0
lines changed

14 files changed

+562
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#version 100
2+
3+
precision mediump float;
4+
5+
varying vec3 fragPosition;
6+
varying vec2 fragTexCoord;
7+
varying vec4 fragColor;
8+
varying vec3 fragNormal;
9+
10+
uniform sampler2D texture0;
11+
uniform vec4 colDiffuse;
12+
uniform vec3 viewPos;
13+
uniform float numBands;
14+
15+
struct Light {
16+
int enabled;
17+
int type;
18+
vec3 position;
19+
vec3 target;
20+
vec4 color;
21+
};
22+
uniform Light lights[4];
23+
24+
void main()
25+
{
26+
vec4 texColor = texture2D(texture0, fragTexCoord);
27+
vec3 baseColor = texColor.rgb * fragColor.rgb * colDiffuse.rgb;
28+
vec3 norm = normalize(fragNormal);
29+
30+
float lightAccum = 0.08; // ambient floor
31+
32+
for (int i = 0; i < 4; i++)
33+
{
34+
if (lights[i].enabled == 1) // no continue in GLSL ES 1.0
35+
{
36+
vec3 lightDir;
37+
if (lights[i].type == 0)
38+
{
39+
// Directional: direction is from position toward target.
40+
lightDir = normalize(lights[i].position - lights[i].target);
41+
}
42+
else
43+
{
44+
// Point: direction from surface to light.
45+
lightDir = normalize(lights[i].position - fragPosition);
46+
}
47+
48+
float NdotL = max(dot(norm, lightDir), 0.0);
49+
50+
// Quantize NdotL into numBands discrete steps.
51+
float quantized = min(floor(NdotL * numBands), numBands - 1.0) / (numBands - 1.0);
52+
lightAccum += quantized * lights[i].color.r;
53+
}
54+
}
55+
56+
lightAccum = clamp(lightAccum, 0.0, 1.0);
57+
gl_FragColor = vec4(baseColor * lightAccum, texColor.a * colDiffuse.a);
58+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#version 100
2+
3+
attribute vec3 vertexPosition;
4+
attribute vec2 vertexTexCoord;
5+
attribute vec3 vertexNormal;
6+
attribute vec4 vertexColor;
7+
8+
uniform mat4 mvp;
9+
uniform mat4 matModel;
10+
11+
varying vec3 fragPosition;
12+
varying vec2 fragTexCoord;
13+
varying vec4 fragColor;
14+
varying vec3 fragNormal;
15+
16+
mat3 inverse(mat3 m)
17+
{
18+
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
19+
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
20+
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
21+
float b01 = a22*a11 - a12*a21;
22+
float b11 = -a22*a10 + a12*a20;
23+
float b21 = a21*a10 - a11*a20;
24+
float det = a00*b01 + a01*b11 + a02*b21;
25+
return mat3(b01, (-a22*a01 + a02*a21), ( a12*a01 - a02*a11),
26+
b11, ( a22*a00 - a02*a20), (-a12*a00 + a02*a10),
27+
b21, (-a21*a00 + a01*a20), ( a11*a00 - a01*a10)) / det;
28+
}
29+
30+
mat3 transpose(mat3 m)
31+
{
32+
return mat3(m[0][0], m[1][0], m[2][0],
33+
m[0][1], m[1][1], m[2][1],
34+
m[0][2], m[1][2], m[2][2]);
35+
}
36+
37+
void main()
38+
{
39+
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
40+
fragTexCoord = vertexTexCoord;
41+
fragColor = vertexColor;
42+
43+
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
44+
fragNormal = normalize(normalMatrix * vertexNormal);
45+
46+
gl_Position = mvp * vec4(vertexPosition, 1.0);
47+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#version 100
2+
3+
precision mediump float;
4+
5+
void main()
6+
{
7+
gl_FragColor = vec4(0.05, 0.05, 0.05, 1.0);
8+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#version 100
2+
3+
attribute vec3 vertexPosition;
4+
attribute vec3 vertexNormal;
5+
attribute vec2 vertexTexCoord;
6+
attribute vec4 vertexColor;
7+
8+
uniform mat4 mvp;
9+
uniform float outlineThickness;
10+
11+
void main()
12+
{
13+
vec3 extruded = vertexPosition + vertexNormal * outlineThickness;
14+
gl_Position = mvp * vec4(extruded, 1.0);
15+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#version 120
2+
3+
varying vec3 fragPosition;
4+
varying vec2 fragTexCoord;
5+
varying vec4 fragColor;
6+
varying vec3 fragNormal;
7+
8+
uniform sampler2D texture0;
9+
uniform vec4 colDiffuse;
10+
uniform vec3 viewPos;
11+
uniform float numBands;
12+
13+
struct Light {
14+
int enabled;
15+
int type;
16+
vec3 position;
17+
vec3 target;
18+
vec4 color;
19+
};
20+
uniform Light lights[4];
21+
22+
void main()
23+
{
24+
vec4 texColor = texture2D(texture0, fragTexCoord);
25+
vec3 baseColor = texColor.rgb * fragColor.rgb * colDiffuse.rgb;
26+
vec3 norm = normalize(fragNormal);
27+
28+
float lightAccum = 0.08; // ambient floor
29+
30+
for (int i = 0; i < 4; i++)
31+
{
32+
if (lights[i].enabled == 1)
33+
{
34+
vec3 lightDir;
35+
if (lights[i].type == 0)
36+
{
37+
// Directional: direction is from position toward target.
38+
lightDir = normalize(lights[i].position - lights[i].target);
39+
}
40+
else
41+
{
42+
// Point: direction from surface to light.
43+
lightDir = normalize(lights[i].position - fragPosition);
44+
}
45+
46+
float NdotL = max(dot(norm, lightDir), 0.0);
47+
48+
// Quantize NdotL into numBands discrete steps.
49+
float quantized = min(floor(NdotL * numBands), numBands - 1.0) / (numBands - 1.0);
50+
lightAccum += quantized * lights[i].color.r;
51+
}
52+
}
53+
54+
lightAccum = clamp(lightAccum, 0.0, 1.0);
55+
gl_FragColor = vec4(baseColor * lightAccum, texColor.a * colDiffuse.a);
56+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#version 120
2+
3+
attribute vec3 vertexPosition;
4+
attribute vec2 vertexTexCoord;
5+
attribute vec3 vertexNormal;
6+
attribute vec4 vertexColor;
7+
8+
uniform mat4 mvp;
9+
uniform mat4 matModel;
10+
11+
varying vec3 fragPosition;
12+
varying vec2 fragTexCoord;
13+
varying vec4 fragColor;
14+
varying vec3 fragNormal;
15+
16+
// inverse() and transpose() are not built-in until GLSL 1.40
17+
mat3 inverse(mat3 m)
18+
{
19+
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
20+
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
21+
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
22+
float b01 = a22*a11 - a12*a21;
23+
float b11 = -a22*a10 + a12*a20;
24+
float b21 = a21*a10 - a11*a20;
25+
float det = a00*b01 + a01*b11 + a02*b21;
26+
return mat3(b01, (-a22*a01 + a02*a21), ( a12*a01 - a02*a11),
27+
b11, ( a22*a00 - a02*a20), (-a12*a00 + a02*a10),
28+
b21, (-a21*a00 + a01*a20), ( a11*a00 - a01*a10)) / det;
29+
}
30+
31+
mat3 transpose(mat3 m)
32+
{
33+
return mat3(m[0][0], m[1][0], m[2][0],
34+
m[0][1], m[1][1], m[2][1],
35+
m[0][2], m[1][2], m[2][2]);
36+
}
37+
38+
void main()
39+
{
40+
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
41+
fragTexCoord = vertexTexCoord;
42+
fragColor = vertexColor;
43+
44+
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
45+
fragNormal = normalize(normalMatrix * vertexNormal);
46+
47+
gl_Position = mvp * vec4(vertexPosition, 1.0);
48+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#version 120
2+
3+
void main()
4+
{
5+
gl_FragColor = vec4(0.05, 0.05, 0.05, 1.0);
6+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#version 120
2+
3+
attribute vec3 vertexPosition;
4+
attribute vec3 vertexNormal;
5+
attribute vec2 vertexTexCoord;
6+
attribute vec4 vertexColor;
7+
8+
uniform mat4 mvp;
9+
uniform float outlineThickness;
10+
11+
void main()
12+
{
13+
vec3 extruded = vertexPosition + vertexNormal * outlineThickness;
14+
gl_Position = mvp * vec4(extruded, 1.0);
15+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#version 330
2+
3+
in vec3 fragPosition;
4+
in vec2 fragTexCoord;
5+
in vec4 fragColor;
6+
in vec3 fragNormal;
7+
8+
// Raylib standard uniforms
9+
uniform sampler2D texture0;
10+
uniform vec4 colDiffuse;
11+
12+
// View position for future specular / fresnel use.
13+
uniform vec3 viewPos;
14+
15+
// Number of discrete toon bands (2 = hard binary, 10 = default, 20 = near-smooth).
16+
uniform float numBands;
17+
18+
// rlights.h compatible light block.
19+
struct Light {
20+
int enabled;
21+
int type; // 0 = directional, 1 = point
22+
vec3 position;
23+
vec3 target;
24+
vec4 color;
25+
float attenuation;
26+
};
27+
uniform Light lights[4];
28+
29+
out vec4 finalColor;
30+
31+
void main() {
32+
vec4 texColor = texture(texture0, fragTexCoord);
33+
vec3 baseColor = texColor.rgb * fragColor.rgb * colDiffuse.rgb;
34+
vec3 norm = normalize(fragNormal);
35+
36+
float lightAccum = 0.08; // ambient floor
37+
38+
for (int i = 0; i < 4; i++) {
39+
if (lights[i].enabled == 0) continue;
40+
41+
vec3 lightDir;
42+
if (lights[i].type == 0) {
43+
// Directional: direction is from position toward target.
44+
lightDir = normalize(lights[i].position - lights[i].target);
45+
} else {
46+
// Point: direction from surface to light.
47+
lightDir = normalize(lights[i].position - fragPosition);
48+
}
49+
50+
float NdotL = max(dot(norm, lightDir), 0.0);
51+
52+
// Quantize NdotL into numBands discrete steps.
53+
// min() guards against NdotL == 1.0 producing an out-of-range index.
54+
float quantized = min(floor(NdotL * numBands), numBands - 1.0) / (numBands - 1.0);
55+
lightAccum += quantized * lights[i].color.r;
56+
}
57+
58+
lightAccum = clamp(lightAccum, 0.0, 1.0);
59+
finalColor = vec4(baseColor * lightAccum, texColor.a * colDiffuse.a);
60+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#version 330
2+
3+
// Raylib standard attributes
4+
in vec3 vertexPosition;
5+
in vec2 vertexTexCoord;
6+
in vec3 vertexNormal;
7+
in vec4 vertexColor;
8+
9+
// Raylib standard uniforms
10+
uniform mat4 mvp;
11+
uniform mat4 matModel;
12+
uniform mat4 matNormal;
13+
14+
out vec3 fragPosition;
15+
out vec2 fragTexCoord;
16+
out vec4 fragColor;
17+
out vec3 fragNormal;
18+
19+
void main() {
20+
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
21+
fragTexCoord = vertexTexCoord;
22+
fragColor = vertexColor;
23+
fragNormal = normalize(vec3(matNormal * vec4(vertexNormal, 0.0)));
24+
gl_Position = mvp * vec4(vertexPosition, 1.0);
25+
}

0 commit comments

Comments
 (0)