diff --git a/data/shaders/sunlightshadow.frag b/data/shaders/sunlightshadow.frag index 77340c5e0..e7a5692ec 100644 --- a/data/shaders/sunlightshadow.frag +++ b/data/shaders/sunlightshadow.frag @@ -11,6 +11,7 @@ uniform float split1; uniform float split2; uniform float splitmax; uniform float shadow_res; +uniform float overlap_proportion; uniform vec3 sundirection; uniform vec3 sun_color; @@ -30,25 +31,56 @@ out vec4 Spec; #stk_include "utils/getPosFromUVDepth.frag" #stk_include "utils/SunMRP.frag" -float getShadowFactor(vec3 pos, int index) +// https://web.archive.org/web/20230210095515/http://the-witness.net/news/2013/09/shadow-mapping-summary-part-1 +float getShadowFactor(vec3 pos, int index, float bias) { vec4 shadowcoord = (u_shadow_projection_view_matrices[index] * u_inverse_view_matrix * vec4(pos, 1.0)); shadowcoord.xy /= shadowcoord.w; vec2 shadowtexcoord = shadowcoord.xy * 0.5 + 0.5; - //float d = .5 * shadowcoord.z + .5; - float d = .5 * shadowcoord.z + .5 - 1. / (shadow_res * 5.); + float d = .5 * shadowcoord.z + .5 - bias; - float result = 0.; + vec2 uv = shadowtexcoord * shadow_res; + vec2 base_uv = floor(uv + 0.5); + float s = (uv.x + 0.5 - base_uv.x); + float t = (uv.y + 0.5 - base_uv.y); + base_uv -= 0.5; + base_uv /= shadow_res; - for (float i = -1.; i <= 1.; i += 1.) - { - for (float j = -1.; j <= 1.; j += 1.) - { - result += texture(shadowtex, vec4(shadowtexcoord + vec2(i,j) / shadow_res, float(index), d)); - } - } + float uw0 = (4.0 - 3.0 * s); + float uw1 = 7.0; + float uw2 = (1.0 + 3.0 * s); - return result / 9.; + float u0 = (3.0 - 2.0 * s) / uw0 - 2.0; + float u1 = (3.0 + s) / uw1; + float u2 = s / uw2 + 2.0; + + float vw0 = (4.0 - 3.0 * t); + float vw1 = 7.0; + float vw2 = (1.0 + 3.0 * t); + + float v0 = (3.0 - 2.0 * t) / vw0 - 2.0; + float v1 = (3.0 + t) / vw1; + float v2 = t / vw2 + 2.0; + + float sum = 0.0; + + sum += uw0 * vw0 * texture(shadowtex, vec4(base_uv + (vec2(u0, v0) / shadow_res), float(index), d)); + sum += uw1 * vw0 * texture(shadowtex, vec4(base_uv + (vec2(u1, v0) / shadow_res), float(index), d)); + sum += uw2 * vw0 * texture(shadowtex, vec4(base_uv + (vec2(u2, v0) / shadow_res), float(index), d)); + + sum += uw0 * vw1 * texture(shadowtex, vec4(base_uv + (vec2(u0, v1) / shadow_res), float(index), d)); + sum += uw1 * vw1 * texture(shadowtex, vec4(base_uv + (vec2(u1, v1) / shadow_res), float(index), d)); + sum += uw2 * vw1 * texture(shadowtex, vec4(base_uv + (vec2(u2, v1) / shadow_res), float(index), d)); + + sum += uw0 * vw2 * texture(shadowtex, vec4(base_uv + (vec2(u0, v2) / shadow_res), float(index), d)); + sum += uw1 * vw2 * texture(shadowtex, vec4(base_uv + (vec2(u1, v2) / shadow_res), float(index), d)); + sum += uw2 * vw2 * texture(shadowtex, vec4(base_uv + (vec2(u2, v2) / shadow_res), float(index), d)); + + return sum / 144.0; +} + +float blend_start(float x) { + return x * (1.0 - overlap_proportion); } void main() { @@ -68,16 +100,30 @@ void main() { // Shadows float factor; - if (xpos.z < split0) - factor = getShadowFactor(xpos.xyz, 0); - else if (xpos.z < split1) - factor = getShadowFactor(xpos.xyz, 1); - else if (xpos.z < split2) - factor = getShadowFactor(xpos.xyz, 2); - else if (xpos.z < splitmax) - factor = getShadowFactor(xpos.xyz, 3); - else + float bias = max(1.0 - NdotL, .2) / shadow_res; + if (xpos.z < split0) { + factor = getShadowFactor(xpos.xyz, 0, bias); + if (xpos.z > blend_start(split0)) { + factor = mix(factor, getShadowFactor(xpos.xyz, 1, bias), (xpos.z - blend_start(split0)) / split0 / overlap_proportion); + } + } else if (xpos.z < split1) { + factor = getShadowFactor(xpos.xyz, 1, bias); + if (xpos.z > blend_start(split1)) { + factor = mix(factor, getShadowFactor(xpos.xyz, 2, bias), (xpos.z - blend_start(split1)) / split1 / overlap_proportion); + } + } else if (xpos.z < split2) { + factor = getShadowFactor(xpos.xyz, 2, bias); + if (xpos.z > blend_start(split2)) { + factor = mix(factor, getShadowFactor(xpos.xyz, 3, bias), (xpos.z - blend_start(split2)) / split2 / overlap_proportion); + } + } else if (xpos.z < splitmax) { + factor = getShadowFactor(xpos.xyz, 3, bias); + if (xpos.z > blend_start(splitmax)) { + factor = mix(factor, 1.0, (xpos.z - blend_start(splitmax)) / splitmax / overlap_proportion); + } + } else { factor = 1.; + } Diff = vec4(factor * NdotL * Diffuse * sun_color, 1.); Spec = vec4(factor * NdotL * Specular * sun_color, 1.); diff --git a/src/graphics/lighting_passes.cpp b/src/graphics/lighting_passes.cpp index 39962948f..d30c6cf4c 100644 --- a/src/graphics/lighting_passes.cpp +++ b/src/graphics/lighting_passes.cpp @@ -201,7 +201,7 @@ public: // ============================================================================ class ShadowedSunLightShaderPCF : public TextureShader { public: @@ -215,7 +215,7 @@ public: 1, "dtex", ST_NEAREST_FILTERED, 8, "shadowtex", ST_SHADOW_SAMPLER); assignUniforms("split0", "split1", "split2", "splitmax", "shadow_res", - "sundirection", "sun_color"); + "overlap_proportion", "sundirection", "sun_color"); } // ShadowedSunLightShaderPCF // ------------------------------------------------------------------------ void render(GLuint normal_depth_texture, @@ -232,6 +232,7 @@ public: ShadowMatrices::m_shadow_split[3], ShadowMatrices::m_shadow_split[4], float(UserConfigParams::m_shadows_resolution), + ShadowMatrices::m_shadow_overlap_proportion, direction, col); } // render diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index f84f13cfa..6084fdbce 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -77,26 +77,6 @@ public: } // render }; // Gaussian3HBlurShader -// ============================================================================ -class ComputeShadowBlurVShader : public TextureShader > -{ -public: - GLuint m_dest_tu; - ComputeShadowBlurVShader() - { -#if !defined(USE_GLES2) - loadProgram(OBJECT, GL_COMPUTE_SHADER, "blurshadowV.comp"); - m_dest_tu = 1; - assignUniforms("pixel", "weights"); - assignSamplerNames(0, "source", ST_NEARED_CLAMPED_FILTERED); - assignTextureUnit(m_dest_tu, "dest"); -#endif - } // ComputeShadowBlurVShader - -}; // ComputeShadowBlurVShader - // ============================================================================ class Gaussian6VBlurShader : public TextureShader @@ -174,23 +154,6 @@ public: assignTextureUnit(m_dest_tu, "dest"); } // ComputeGaussian6HBlurShader }; // ComputeGaussian6HBlurShader - -// ============================================================================ -class ComputeShadowBlurHShader : public TextureShader > -{ -public: - GLuint m_dest_tu; - ComputeShadowBlurHShader() - { - loadProgram(OBJECT, GL_COMPUTE_SHADER, "blurshadowH.comp"); - m_dest_tu = 1; - assignUniforms("pixel", "weights"); - assignSamplerNames(0, "source", ST_NEARED_CLAMPED_FILTERED); - assignTextureUnit(m_dest_tu, "dest"); - } // ComputeShadowBlurHShader -}; // ComputeShadowBlurHShader #endif // ============================================================================ diff --git a/src/graphics/shadow_matrices.cpp b/src/graphics/shadow_matrices.cpp index 2e202c71e..1d048f721 100644 --- a/src/graphics/shadow_matrices.cpp +++ b/src/graphics/shadow_matrices.cpp @@ -39,7 +39,8 @@ #define MAX2(a, b) ((a) > (b) ? (a) : (b)) #define MIN2(a, b) ((a) > (b) ? (b) : (a)) -float ShadowMatrices:: m_shadow_split[5] = { 1., 5., 20., 50., 150 }; +float ShadowMatrices:: m_shadow_split[5] = { 1., 5., 20., 60., 150 }; +float ShadowMatrices:: m_shadow_overlap_proportion = 0.2; // ============================================================================ class ViewFrustrumShader : public Shader @@ -236,9 +237,9 @@ void ShadowMatrices::computeMatrixesAndCameras(scene::ICameraSceneNode *const ca float NearValues[] = { ShadowMatrices::m_shadow_split[0], - ShadowMatrices::m_shadow_split[1], - ShadowMatrices::m_shadow_split[2], - ShadowMatrices::m_shadow_split[3] + ShadowMatrices::m_shadow_split[1] * (1.0f - m_shadow_overlap_proportion), + ShadowMatrices::m_shadow_split[2] * (1.0f - m_shadow_overlap_proportion), + ShadowMatrices::m_shadow_split[3] * (1.0f - m_shadow_overlap_proportion) }; // Shadow Matrixes and cameras diff --git a/src/graphics/shadow_matrices.hpp b/src/graphics/shadow_matrices.hpp index 793107977..82918955a 100644 --- a/src/graphics/shadow_matrices.hpp +++ b/src/graphics/shadow_matrices.hpp @@ -40,6 +40,7 @@ class ShadowMatrices { public: static float m_shadow_split[5]; + static float m_shadow_overlap_proportion; private: std::vector m_sun_ortho_matrices;