Browse Source

Merge pull request #18770 from gkjohnson/csm-change-fade-computation

CSM: change fade margin computation
Mr.doob 5 years ago
parent
commit
b1fac2449b
2 changed files with 13 additions and 7 deletions
  1. 12 7
      examples/jsm/csm/Shader.js
  2. 1 0
      examples/webgl_shadowmap_csm.html

+ 12 - 7
examples/jsm/csm/Shader.js

@@ -78,16 +78,21 @@ IncidentLight directLight;
 	DirectionalLightShadow directionalLightShadow;
 	DirectionalLightShadow directionalLightShadow;
 	#endif
 	#endif
 
 
-	#if defined( CSM_FADE )
+	#if defined( USE_SHADOWMAP ) && defined( CSM_FADE )
 	for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
 	for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
 
 
 		directionalLight = directionalLights[ i ];
 		directionalLight = directionalLights[ i ];
 		getDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );
 		getDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );
 
 
-		float margin = 0.25 * pow( linearDepth, 2.0 );
-		float csmx = CSM_cascades[ i ].x - margin / 2.0;
-		float csmy = CSM_cascades[ i ].y + margin / 2.0;
-		if( i < NUM_DIR_LIGHT_SHADOWS && linearDepth >= csmx && ( linearDepth < csmy ||  i == CSM_CASCADES - 1 ) ) {
+		// NOTE: Depth gets larger away from the camera.
+		// cascade.x is closer, cascade.y is further
+		vec2 cascade = CSM_cascades[ i ];
+		float cascadeCenter = ( cascade.x + cascade.y ) / 2.0;
+		float closestEdge = linearDepth < cascadeCenter ? cascade.x : cascade.y;
+		float margin = 0.25 * pow( closestEdge, 2.0 );
+		float csmx = cascade.x - margin / 2.0;
+		float csmy = cascade.y + margin / 2.0;
+		if( i < NUM_DIR_LIGHT_SHADOWS && linearDepth >= csmx && ( linearDepth < csmy || i == CSM_CASCADES - 1 ) ) {
 
 
 			float dist = min( linearDepth - csmx, csmy - linearDepth );
 			float dist = min( linearDepth - csmx, csmy - linearDepth );
 			float ratio = clamp( dist / margin, 0.0, 1.0 );
 			float ratio = clamp( dist / margin, 0.0, 1.0 );
@@ -97,7 +102,7 @@ IncidentLight directLight;
 				directionalLightShadow = directionalLightShadows[ i ];
 				directionalLightShadow = directionalLightShadows[ i ];
 				directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
 				directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
 
 
-				bool shouldFadeLastCascade = i == CSM_CASCADES - 1 && linearDepth > ( csmx + csmy ) / 2.0;
+				bool shouldFadeLastCascade = i == CSM_CASCADES - 1 && linearDepth > cascadeCenter;
 				directLight.color = mix( prevColor, directLight.color, shouldFadeLastCascade ? ratio : 1.0 );
 				directLight.color = mix( prevColor, directLight.color, shouldFadeLastCascade ? ratio : 1.0 );
 
 
 			}
 			}
@@ -105,7 +110,7 @@ IncidentLight directLight;
 			ReflectedLight prevLight = reflectedLight;
 			ReflectedLight prevLight = reflectedLight;
 			RE_Direct( directLight, geometry, material, reflectedLight );
 			RE_Direct( directLight, geometry, material, reflectedLight );
 
 
-			bool shouldBlend = i != CSM_CASCADES - 1 || i == CSM_CASCADES - 1 && linearDepth < ( csmx + csmy ) / 2.0;
+			bool shouldBlend = i != CSM_CASCADES - 1 || i == CSM_CASCADES - 1 && linearDepth < cascadeCenter;
 			float blendRatio = shouldBlend ? ratio : 1.0;
 			float blendRatio = shouldBlend ? ratio : 1.0;
 
 
 			reflectedLight.directDiffuse = mix( prevLight.directDiffuse, reflectedLight.directDiffuse, blendRatio );
 			reflectedLight.directDiffuse = mix( prevLight.directDiffuse, reflectedLight.directDiffuse, blendRatio );

+ 1 - 0
examples/webgl_shadowmap_csm.html

@@ -212,6 +212,7 @@
 					camera.updateProjectionMatrix();
 					camera.updateProjectionMatrix();
 
 
 					updateOrthoCamera();
 					updateOrthoCamera();
+					csm.updateFrustums();
 
 
 					renderer.setSize( window.innerWidth, window.innerHeight );
 					renderer.setSize( window.innerWidth, window.innerHeight );