|
|
|
@ -7,7 +7,8 @@ in vec2 uv_in;
|
|
|
|
|
out vec3 pos;
|
|
|
|
|
out vec2 uv;
|
|
|
|
|
out vec4 light_space_fragment_position;
|
|
|
|
|
|
|
|
|
|
out vec3 light_dir;
|
|
|
|
|
out vec4 world_space_frag_pos;
|
|
|
|
|
|
|
|
|
|
uniform vs_params {
|
|
|
|
|
mat4 model;
|
|
|
|
@ -20,10 +21,13 @@ void main() {
|
|
|
|
|
pos = pos_in;
|
|
|
|
|
uv = uv_in;
|
|
|
|
|
|
|
|
|
|
vec4 world_space_frag_pos = model * vec4(pos_in, 1.0);
|
|
|
|
|
world_space_frag_pos = model * vec4(pos_in, 1.0);
|
|
|
|
|
vec4 frag_pos = view * world_space_frag_pos;
|
|
|
|
|
gl_Position = projection * frag_pos;
|
|
|
|
|
|
|
|
|
|
//@Speed I think we can just take the third row here and be fine.
|
|
|
|
|
light_dir = normalize(inverse(directional_light_space_matrix) * vec4(0.0, 0.0, -1.0, 0.0)).xyz;
|
|
|
|
|
|
|
|
|
|
light_space_fragment_position = directional_light_space_matrix * vec4(world_space_frag_pos.xyz, 1.0);
|
|
|
|
|
}
|
|
|
|
|
@end
|
|
|
|
@ -40,6 +44,8 @@ uniform fs_params {
|
|
|
|
|
in vec3 pos;
|
|
|
|
|
in vec2 uv;
|
|
|
|
|
in vec4 light_space_fragment_position;
|
|
|
|
|
in vec3 light_dir;
|
|
|
|
|
in vec4 world_space_frag_pos;
|
|
|
|
|
|
|
|
|
|
out vec4 frag_color;
|
|
|
|
|
|
|
|
|
@ -47,7 +53,7 @@ float decodeDepth(vec4 rgba) {
|
|
|
|
|
return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float do_shadow_sample(sampler2D shadowMap, vec2 uv, float scene_depth) {
|
|
|
|
|
float do_shadow_sample(sampler2D shadowMap, vec2 uv, float scene_depth, float n_dot_l) {
|
|
|
|
|
{
|
|
|
|
|
//WebGL does not support GL_CLAMP_TO_BORDER, or border colors at all it seems, so we have to check explicitly.
|
|
|
|
|
//This will probably slow down other versions which do support texture borders, but the current system does
|
|
|
|
@ -56,12 +62,21 @@ float do_shadow_sample(sampler2D shadowMap, vec2 uv, float scene_depth) {
|
|
|
|
|
return 1.0;
|
|
|
|
|
}
|
|
|
|
|
float map_depth = decodeDepth(texture(shadowMap, uv));
|
|
|
|
|
map_depth += 0.001;//bias to counter self-shadowing
|
|
|
|
|
|
|
|
|
|
// float bias = max(0.03f * (1.0f - n_dot_l), 0.005f);
|
|
|
|
|
// bias = clamp(bias, 0.0, 0.01);
|
|
|
|
|
|
|
|
|
|
float offset_scale_N = sqrt(1 - n_dot_l*n_dot_l);
|
|
|
|
|
float offset_scale_L = offset_scale_N / n_dot_l;
|
|
|
|
|
float bias = 0.0002 * offset_scale_N + 0.0001 * offset_scale_L;
|
|
|
|
|
|
|
|
|
|
map_depth += bias;
|
|
|
|
|
|
|
|
|
|
return step(scene_depth, map_depth);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float bilinear_shadow_sample(sampler2D shadowMap, vec2 uv, int texture_width, int texture_height, float scene_depth_light_space) {
|
|
|
|
|
float bilinear_shadow_sample(sampler2D shadowMap, vec2 uv, int texture_width, int texture_height, float scene_depth_light_space, float n_dot_l) {
|
|
|
|
|
vec2 texture_dim = vec2(float(texture_width), float(texture_height));
|
|
|
|
|
vec2 texel_dim = vec2(1.0 / float(texture_width ), 1.0 / float(texture_height));
|
|
|
|
|
|
|
|
|
@ -75,10 +90,10 @@ float bilinear_shadow_sample(sampler2D shadowMap, vec2 uv, int texture_width, in
|
|
|
|
|
vec2 uv_2 = vec2(texel_uv_floor.x, texel_uv_ceil.y );
|
|
|
|
|
vec2 uv_3 = vec2(texel_uv_ceil.x , texel_uv_ceil.y );
|
|
|
|
|
|
|
|
|
|
float bl = do_shadow_sample(shadowMap, uv_0, scene_depth_light_space);
|
|
|
|
|
float br = do_shadow_sample(shadowMap, uv_1, scene_depth_light_space);
|
|
|
|
|
float tl = do_shadow_sample(shadowMap, uv_2, scene_depth_light_space);
|
|
|
|
|
float tr = do_shadow_sample(shadowMap, uv_3, scene_depth_light_space);
|
|
|
|
|
float bl = do_shadow_sample(shadowMap, uv_0, scene_depth_light_space, n_dot_l);
|
|
|
|
|
float br = do_shadow_sample(shadowMap, uv_1, scene_depth_light_space, n_dot_l);
|
|
|
|
|
float tl = do_shadow_sample(shadowMap, uv_2, scene_depth_light_space, n_dot_l);
|
|
|
|
|
float tr = do_shadow_sample(shadowMap, uv_3, scene_depth_light_space, n_dot_l);
|
|
|
|
|
|
|
|
|
|
vec2 interp = fract(texel_uv);
|
|
|
|
|
|
|
|
|
@ -89,7 +104,7 @@ float bilinear_shadow_sample(sampler2D shadowMap, vec2 uv, int texture_width, in
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float calculate_shadow_factor(sampler2D shadowMap, vec4 light_space_fragment_position) {
|
|
|
|
|
float calculate_shadow_factor(sampler2D shadowMap, vec4 light_space_fragment_position, float n_dot_l) {
|
|
|
|
|
float shadow = 1.0;
|
|
|
|
|
|
|
|
|
|
vec3 projected_coords = light_space_fragment_position.xyz / light_space_fragment_position.w;
|
|
|
|
@ -109,11 +124,13 @@ float calculate_shadow_factor(sampler2D shadowMap, vec4 light_space_fragment_pos
|
|
|
|
|
for (int y=-2; y<=2; y++) {
|
|
|
|
|
vec2 off = vec2(x*texel_step_size, y*texel_step_size);
|
|
|
|
|
// shadow += do_shadow_sample(shadowMap, shadow_uv+off, current_depth);
|
|
|
|
|
shadow += bilinear_shadow_sample(shadowMap, shadow_uv+off, shadow_map_dimension, shadow_map_dimension, current_depth);
|
|
|
|
|
shadow += bilinear_shadow_sample(shadowMap, shadow_uv+off, shadow_map_dimension, shadow_map_dimension, current_depth, n_dot_l);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
shadow /= 25.0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return shadow;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -126,12 +143,17 @@ void main() {
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
vec3 light_dir = normalize(vec3(1, -1, 0));
|
|
|
|
|
|
|
|
|
|
float shadow_factor = calculate_shadow_factor(shadow_map, light_space_fragment_position);
|
|
|
|
|
shadow_factor = shadow_factor * 0.5 + 0.5;
|
|
|
|
|
vec3 normal = normalize(cross(dFdx(world_space_frag_pos.xyz), dFdy(world_space_frag_pos.xyz)));
|
|
|
|
|
|
|
|
|
|
float n_dot_l = clamp(dot(normal, light_dir), 0.0, 1.0);
|
|
|
|
|
float shadow_factor = calculate_shadow_factor(shadow_map, light_space_fragment_position, n_dot_l);
|
|
|
|
|
|
|
|
|
|
float lighting_factor = shadow_factor * n_dot_l;
|
|
|
|
|
lighting_factor = lighting_factor * 0.5 + 0.5;
|
|
|
|
|
|
|
|
|
|
frag_color = vec4(col.rgb*lighting_factor, 1.0);
|
|
|
|
|
|
|
|
|
|
frag_color = vec4(col.rgb*shadow_factor, 1.0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@end
|
|
|
|
|