tangled
alpha
login
or
join now
stanislaw.malolepszy.org
/
goodluck
1
fork
atom
A hackable template for creating small and fast browser games.
1
fork
atom
overview
issues
pulls
pipelines
(ForwardShading) Fix shadows ata small angles
Staś Małolepszy
2 years ago
bd32e00a
a6b15c1c
+12
-19
2 changed files
expand all
collapse all
unified
split
ForwardShading
scenes
sce_stage.ts
materials
mat_forward_colored_shadows.ts
+1
-1
ForwardShading/scenes/sce_stage.ts
···
23
23
game.ViewportResized = true;
24
24
25
25
// Camera.
26
26
-
instantiate(game, [...blueprint_camera(game), set_position(0, 0, 7), set_rotation(0, 180, 0)]);
26
26
+
instantiate(game, [...blueprint_camera(game), set_position(0, 0, 9), set_rotation(0, 180, 0)]);
27
27
28
28
// Minimap Camera.
29
29
instantiate(game, [
+11
-18
materials/mat_forward_colored_shadows.ts
···
12
12
uniform mat4 pv;
13
13
uniform mat4 world;
14
14
uniform mat4 self;
15
15
+
uniform mat4 shadow_space;
15
16
16
17
layout(location=${Attribute.Position}) in vec4 attr_position;
17
18
layout(location=${Attribute.Normal}) in vec3 attr_normal;
18
19
19
20
out vec4 vert_position;
21
21
+
out vec4 vert_position_shadow;
20
22
out vec3 vert_normal;
21
23
22
24
void main() {
23
25
vert_position = world * attr_position;
26
26
+
vert_position_shadow = shadow_space * vert_position;
24
27
vert_normal = (vec4(attr_normal, 0.0) * self).xyz;
25
28
gl_Position = pv * vert_position;
26
29
}
···
28
31
29
32
let fragment = `#version 300 es\n
30
33
precision mediump float;
31
31
-
precision lowp sampler2DShadow;
34
34
+
precision mediump sampler2DShadow;
32
35
33
36
uniform vec3 eye;
34
37
uniform vec4 diffuse_color;
···
36
39
uniform vec4 emissive_color;
37
40
uniform vec4 light_positions[${MAX_FORWARD_LIGHTS}];
38
41
uniform vec4 light_details[${MAX_FORWARD_LIGHTS}];
39
39
-
uniform mat4 shadow_space;
40
42
uniform sampler2DShadow shadow_map;
41
43
42
44
in vec4 vert_position;
45
45
+
in vec4 vert_position_shadow;
43
46
in vec3 vert_normal;
44
47
45
48
out vec4 frag_color;
46
49
47
50
${INCLUDE_GAMMA_CORRECTION}
48
51
49
49
-
// How much shadow to apply at world_pos, expressed as [min, 1]:
50
50
-
// min = completely in shadow, 1 = completely not in shadow
51
51
-
float shadow_factor(vec4 world_pos, float min) {
52
52
-
vec4 shadow_space_pos = shadow_space * world_pos;
53
53
-
vec3 shadow_space_ndc = shadow_space_pos.xyz / shadow_space_pos.w;
54
54
-
// Transform the [-1, 1] NDC to [0, 1] to match the shadow texture data.
55
55
-
shadow_space_ndc = shadow_space_ndc * 0.5 + 0.5;
56
56
-
57
57
-
// Add shadow bias to avoid shadow acne.
58
58
-
shadow_space_ndc.z -= 0.001;
59
59
-
60
60
-
return texture(shadow_map, shadow_space_ndc) * (1.0 - min) + min;
61
61
-
}
62
62
-
63
52
void main() {
64
53
vec3 world_normal = normalize(vert_normal);
65
54
···
81
70
vec3 light_normal;
82
71
if (light_kind == ${LightKind.Directional}) {
83
72
light_normal = light_positions[i].xyz;
73
73
+
// --- Shadow mapping ---
74
74
+
// Apply the shadow source's projection and add bias to avoid shadow acne.
75
75
+
vec3 sample_position = vert_position_shadow.xyz / vert_position_shadow.w - vec3(0, 0, 0.01);
76
76
+
// Transform the [-1, 1] NDC to [0, 1] to match the shadow texture data.
77
77
+
light_intensity *= texture(shadow_map, sample_position * 0.5 + 0.5);
84
78
} else if (light_kind == ${LightKind.Point}) {
85
79
vec3 light_dir = light_positions[i].xyz - vert_position.xyz;
86
80
float light_dist = length(light_dir);
···
112
106
}
113
107
114
108
vec3 emissive_rgb = GAMMA_DECODE(emissive_color.rgb) * emissive_color.a;
115
115
-
vec3 shaded_rgb = light_acc * shadow_factor(vert_position, 0.5);
116
116
-
frag_color= vec4(GAMMA_ENCODE(shaded_rgb + emissive_rgb), diffuse_color.a);
109
109
+
frag_color = vec4(GAMMA_ENCODE(light_acc + emissive_rgb), diffuse_color.a);
117
110
}
118
111
`;
119
112