+ // Shadow
+ uniform lowp int light_kind;
+ uniform bool use_shadows;
+ uniform sampler2D depth_texture;
+ uniform float depth_size;
+ uniform int depth_taps;
+
+ // Shadow effect on the diffuse colors of the fragment at offset `x, y`
+ float shadow_lookup(vec2 depth_coord, float x, float y) {
+ float tap_width = 1.0;
+ float pixel_size = tap_width/depth_size;
+
+ vec2 offset = vec2(x * pixel_size * v_depth_pos.w,
+ y * pixel_size * v_depth_pos.w);
+ depth_coord += offset;
+
+ float depth = v_depth_pos.z/v_depth_pos.w;
+ //vec2 depth_coord = v_depth_pos.xy/v_depth_pos.w;
+ if (depth_coord.x < 0.0 || depth_coord.x > 1.0 || depth_coord.y < 0.0 || depth_coord.y > 1.0) {
+ // Out of the shadow map texture
+ //gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // debug, red out of the light view
+ return 1.0;
+ }
+
+ float shadow_depth = texture2D(depth_texture, depth_coord).r;
+ float bias = 0.0001;
+ if (shadow_depth == 1.0) {
+ // Too far to be in depth texture
+ return 1.0;
+ } else if (shadow_depth <= depth - bias) {
+ // In a shadow
+ //gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0); // debug, blue shadows
+ return 0.2; // TODO replace with a configurable ambient light
+ }
+
+ //gl_FragColor = vec4(0.0, 1.0-(shadow_depth-depth), 0.0, 1.0); // debug, green lit surfaces
+ return 1.0;
+ }
+
+ // Shadow effect on the diffuse colors of the fragment
+ float shadow() {
+ if (!use_shadows) return 1.0;
+
+ vec2 depth_coord = v_depth_pos.xy/v_depth_pos.w;
+
+ float taps = float(depth_taps);
+ float tap_step = 2.00/taps;
+ float sum = 0.0;
+ for (float x = -1.0; x <= 0.99; x += tap_step)
+ for (float y = -1.0; y <= 0.99; y += tap_step)
+ sum += shadow_lookup(depth_coord, x, y);
+ return sum / taps / taps;
+ }
+