From 1b7857ec6020acc9cdf7128729058ab6ae8e6cc3 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Sat, 17 Jan 2026 19:11:59 +0100 Subject: [PATCH] WebGLShadowMap: Fix wrong camera state. (#32777) --- .../shadowmap_pars_fragment.glsl.js | 40 ++++++++++++++++--- src/renderers/shaders/ShaderLib/vsm.glsl.js | 7 ---- src/renderers/webgl/WebGLShadowMap.js | 5 ++- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js b/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js index 265ca8e82c2d75..dd9e98257cc6ca 100644 --- a/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +++ b/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js @@ -155,7 +155,16 @@ export default /* glsl */` float shadow = 1.0; shadowCoord.xyz /= shadowCoord.w; - shadowCoord.z += shadowBias; + + #ifdef USE_REVERSED_DEPTH_BUFFER + + shadowCoord.z -= shadowBias; + + #else + + shadowCoord.z += shadowBias; + + #endif bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0; bool frustumTest = inFrustum && shadowCoord.z <= 1.0; @@ -167,8 +176,16 @@ export default /* glsl */` float mean = distribution.x; float variance = distribution.y * distribution.y; - float hard_shadow = step( shadowCoord.z, mean ); + #ifdef USE_REVERSED_DEPTH_BUFFER + + float hard_shadow = step( mean, shadowCoord.z ); + + #else + + float hard_shadow = step( shadowCoord.z, mean ); + #endif + // Early return if fully lit if ( hard_shadow == 1.0 ) { @@ -205,7 +222,16 @@ export default /* glsl */` float shadow = 1.0; shadowCoord.xyz /= shadowCoord.w; - shadowCoord.z += shadowBias; + + #ifdef USE_REVERSED_DEPTH_BUFFER + + shadowCoord.z -= shadowBias; + + #else + + shadowCoord.z += shadowBias; + + #endif bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0; bool frustumTest = inFrustum && shadowCoord.z <= 1.0; @@ -216,11 +242,13 @@ export default /* glsl */` #ifdef USE_REVERSED_DEPTH_BUFFER - depth = 1.0 - depth; + shadow = step( depth, shadowCoord.z ); - #endif + #else + + shadow = step( shadowCoord.z, depth ); - shadow = step( shadowCoord.z, depth ); + #endif } diff --git a/src/renderers/shaders/ShaderLib/vsm.glsl.js b/src/renderers/shaders/ShaderLib/vsm.glsl.js index efed8385e27991..945662a3f9577d 100644 --- a/src/renderers/shaders/ShaderLib/vsm.glsl.js +++ b/src/renderers/shaders/ShaderLib/vsm.glsl.js @@ -33,13 +33,6 @@ void main() { #else float depth = texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ).r; - - #ifdef USE_REVERSED_DEPTH_BUFFER - - depth = 1.0 - depth; - - #endif - mean += depth; squared_mean += depth * depth; diff --git a/src/renderers/webgl/WebGLShadowMap.js b/src/renderers/webgl/WebGLShadowMap.js index 2e6be20f19d8f8..caaf9dd211ad8b 100644 --- a/src/renderers/webgl/WebGLShadowMap.js +++ b/src/renderers/webgl/WebGLShadowMap.js @@ -197,6 +197,9 @@ function WebGLShadowMap( renderer, objects, capabilities ) { } + const reversedDepthBuffer = renderer.state.buffers.depth.getReversed(); + shadow.camera._reversedDepth = reversedDepthBuffer; + if ( shadow.map === null || typeChanged === true ) { if ( shadow.map !== null ) { @@ -255,8 +258,6 @@ function WebGLShadowMap( renderer, objects, capabilities ) { shadow.map.depthTexture.name = light.name + '.shadowMap'; shadow.map.depthTexture.format = DepthFormat; - const reversedDepthBuffer = renderer.state.buffers.depth.getReversed(); - if ( this.type === PCFShadowMap ) { shadow.map.depthTexture.compareFunction = reversedDepthBuffer ? GreaterEqualCompare : LessEqualCompare;