Skip to content

Commit 28f99d7

Browse files
authored
Fix: CSM lights when shadow maps are disabled (#27358)
* Fix indentation * Allow shadows to be disabled from GUI * Fix: when shadows are disabled, light contribution still needs to be considered
1 parent ca7261b commit 28f99d7

File tree

2 files changed

+70
-48
lines changed

2 files changed

+70
-48
lines changed

examples/jsm/csm/CSMShader.js

+52-47
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ IncidentLight directLight;
6262
vec4 spotColor;
6363
vec3 spotLightCoord;
6464
bool inSpotLightMap;
65-
65+
6666
#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0
6767
SpotLightShadow spotLightShadow;
6868
#endif
@@ -112,76 +112,81 @@ IncidentLight directLight;
112112
#endif
113113
114114
#if defined( USE_SHADOWMAP ) && defined( CSM_FADE )
115-
vec2 cascade;
116-
float cascadeCenter;
117-
float closestEdge;
118-
float margin;
119-
float csmx;
120-
float csmy;
115+
vec2 cascade;
116+
float cascadeCenter;
117+
float closestEdge;
118+
float margin;
119+
float csmx;
120+
float csmy;
121121
122-
#pragma unroll_loop_start
123-
for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
122+
#pragma unroll_loop_start
123+
for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
124124
125-
directionalLight = directionalLights[ i ];
126-
getDirectionalLightInfo( directionalLight, directLight );
125+
directionalLight = directionalLights[ i ];
126+
getDirectionalLightInfo( directionalLight, directLight );
127127
128-
#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )
129-
// NOTE: Depth gets larger away from the camera.
130-
// cascade.x is closer, cascade.y is further
131-
cascade = CSM_cascades[ i ];
132-
cascadeCenter = ( cascade.x + cascade.y ) / 2.0;
133-
closestEdge = linearDepth < cascadeCenter ? cascade.x : cascade.y;
134-
margin = 0.25 * pow( closestEdge, 2.0 );
135-
csmx = cascade.x - margin / 2.0;
136-
csmy = cascade.y + margin / 2.0;
137-
if( linearDepth >= csmx && ( linearDepth < csmy || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 ) ) {
138-
139-
float dist = min( linearDepth - csmx, csmy - linearDepth );
140-
float ratio = clamp( dist / margin, 0.0, 1.0 );
141-
142-
vec3 prevColor = directLight.color;
143-
directionalLightShadow = directionalLightShadows[ i ];
144-
directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
128+
#if ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )
129+
// NOTE: Depth gets larger away from the camera.
130+
// cascade.x is closer, cascade.y is further
131+
cascade = CSM_cascades[ i ];
132+
cascadeCenter = ( cascade.x + cascade.y ) / 2.0;
133+
closestEdge = linearDepth < cascadeCenter ? cascade.x : cascade.y;
134+
margin = 0.25 * pow( closestEdge, 2.0 );
135+
csmx = cascade.x - margin / 2.0;
136+
csmy = cascade.y + margin / 2.0;
137+
if( linearDepth >= csmx && ( linearDepth < csmy || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 ) ) {
145138
146-
bool shouldFadeLastCascade = UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth > cascadeCenter;
147-
directLight.color = mix( prevColor, directLight.color, shouldFadeLastCascade ? ratio : 1.0 );
139+
float dist = min( linearDepth - csmx, csmy - linearDepth );
140+
float ratio = clamp( dist / margin, 0.0, 1.0 );
148141
149-
ReflectedLight prevLight = reflectedLight;
150-
RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
142+
vec3 prevColor = directLight.color;
143+
directionalLightShadow = directionalLightShadows[ i ];
144+
directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
151145
152-
bool shouldBlend = UNROLLED_LOOP_INDEX != CSM_CASCADES - 1 || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth < cascadeCenter;
153-
float blendRatio = shouldBlend ? ratio : 1.0;
146+
bool shouldFadeLastCascade = UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth > cascadeCenter;
147+
directLight.color = mix( prevColor, directLight.color, shouldFadeLastCascade ? ratio : 1.0 );
154148
155-
reflectedLight.directDiffuse = mix( prevLight.directDiffuse, reflectedLight.directDiffuse, blendRatio );
156-
reflectedLight.directSpecular = mix( prevLight.directSpecular, reflectedLight.directSpecular, blendRatio );
157-
reflectedLight.indirectDiffuse = mix( prevLight.indirectDiffuse, reflectedLight.indirectDiffuse, blendRatio );
158-
reflectedLight.indirectSpecular = mix( prevLight.indirectSpecular, reflectedLight.indirectSpecular, blendRatio );
149+
ReflectedLight prevLight = reflectedLight;
150+
RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
159151
160-
}
161-
#endif
152+
bool shouldBlend = UNROLLED_LOOP_INDEX != CSM_CASCADES - 1 || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth < cascadeCenter;
153+
float blendRatio = shouldBlend ? ratio : 1.0;
162154
163-
}
164-
#pragma unroll_loop_end
165-
#else
155+
reflectedLight.directDiffuse = mix( prevLight.directDiffuse, reflectedLight.directDiffuse, blendRatio );
156+
reflectedLight.directSpecular = mix( prevLight.directSpecular, reflectedLight.directSpecular, blendRatio );
157+
reflectedLight.indirectDiffuse = mix( prevLight.indirectDiffuse, reflectedLight.indirectDiffuse, blendRatio );
158+
reflectedLight.indirectSpecular = mix( prevLight.indirectSpecular, reflectedLight.indirectSpecular, blendRatio );
159+
160+
}
161+
#endif
162+
163+
}
164+
#pragma unroll_loop_end
165+
#elif defined (USE_SHADOWMAP)
166166
167167
#pragma unroll_loop_start
168168
for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
169169
170170
directionalLight = directionalLights[ i ];
171171
getDirectionalLightInfo( directionalLight, directLight );
172172
173-
#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )
173+
#if ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )
174174
175-
directionalLightShadow = directionalLightShadows[ i ];
176-
if(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y) directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
175+
directionalLightShadow = directionalLightShadows[ i ];
176+
if(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y) directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
177177
178-
if(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && (linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1)) RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
178+
if(linearDepth >= CSM_cascades[UNROLLED_LOOP_INDEX].x && (linearDepth < CSM_cascades[UNROLLED_LOOP_INDEX].y || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1)) RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
179179
180180
#endif
181181
182182
}
183183
#pragma unroll_loop_end
184184
185+
#elif ( NUM_DIR_LIGHT_SHADOWS > 0 )
186+
// note: no loop here - all CSM lights are in fact one light only
187+
getDirectionalLightInfo( directionalLights[0], directLight );
188+
RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );
189+
185190
#endif
186191
187192
#if ( NUM_DIR_LIGHTS > NUM_DIR_LIGHT_SHADOWS)

examples/webgl_shadowmap_csm.html

+18-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
const params = {
3838
orthographic: false,
3939
fade: false,
40+
shadows: true,
4041
far: 1000,
4142
mode: 'practical',
4243
lightX: - 1,
@@ -82,7 +83,7 @@
8283
renderer = new THREE.WebGLRenderer( { antialias: true } );
8384
renderer.setSize( window.innerWidth, window.innerHeight );
8485
document.body.appendChild( renderer.domElement );
85-
renderer.shadowMap.enabled = true;
86+
renderer.shadowMap.enabled = params.shadows;
8687
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
8788

8889
controls = new OrbitControls( camera, renderer.domElement );
@@ -163,6 +164,22 @@
163164

164165
} );
165166

167+
gui.add( params, 'shadows' ).onChange( function ( value ) {
168+
169+
renderer.shadowMap.enabled = value;
170+
171+
scene.traverse( function ( child ) {
172+
173+
if ( child.material ) {
174+
175+
child.material.needsUpdate = true;
176+
177+
}
178+
179+
} );
180+
181+
} );
182+
166183
gui.add( params, 'far', 1, 5000 ).step( 1 ).name( 'shadow far' ).onChange( function ( value ) {
167184

168185
csm.maxFar = value;

0 commit comments

Comments
 (0)