Bladeren bron

Separate shadow bounds update from update

Garrett Johnson 5 jaren geleden
bovenliggende
commit
8c389278e7
1 gewijzigde bestanden met toevoegingen van 58 en 41 verwijderingen
  1. 58 41
      examples/jsm/csm/CSM.js

+ 58 - 41
examples/jsm/csm/CSM.js

@@ -54,11 +54,9 @@ export default class CSM {
 
 		this.lights = [];
 		this.shaders = new Map();
-		this.createLights();
-
-		this.getBreaks();
-		this.initCascades();
 
+		this.createLights();
+		this.updateFrustums();
 		this.injectInclude();
 
 	}
@@ -93,6 +91,55 @@ export default class CSM {
 
 	}
 
+	updateShadowBounds() {
+
+		const frustums = this.frustums;
+		for ( let i = 0; i < frustums.length; i ++ ) {
+
+			const light = this.lights[ i ];
+			const shadowCam = light.shadow.camera;
+			const frustum = this.frustums[ i ];
+
+			// Get the two points that represent that furthest points on the frustum assuming
+			// that's either the diagonal across the far plane or the diagonal across the whole
+			// frustum itself.
+			const nearVerts = frustum.vertices.near;
+			const farVerts = frustum.vertices.far;
+			const point1 = farVerts[ 0 ];
+			let point2;
+			if ( point1.distanceTo( farVerts[ 2 ] ) > point1.distanceTo( nearVerts[ 2 ] ) ) {
+
+				point2 = farVerts[ 2 ];
+
+			} else {
+
+				point2 = nearVerts[ 2 ];
+
+			}
+
+			let squaredBBWidth = point1.distanceTo( point2 );
+			if ( this.fade ) {
+
+				// expand the shadow extents by the fade margin if fade is enabled.
+				const camera = this.camera;
+				const far = Math.max( camera.far, this.maxFar );
+				const linearDepth = frustum.vertices.far[ 0 ].z / ( far - camera.near );
+				const margin = 0.25 * Math.pow( linearDepth, 2.0 ) * ( far - camera.near );
+
+				squaredBBWidth += margin;
+
+			}
+
+			shadowCam.left = - squaredBBWidth / 2;
+			shadowCam.right = squaredBBWidth / 2;
+			shadowCam.top = squaredBBWidth / 2;
+			shadowCam.bottom = - squaredBBWidth / 2;
+			shadowCam.updateProjectionMatrix();
+
+		}
+
+	}
+
 	getBreaks() {
 
 		const camera = this.camera;
@@ -166,28 +213,15 @@ export default class CSM {
 		for ( let i = 0; i < frustums.length; i ++ ) {
 
 			const light = this.lights[ i ];
+			const shadowCam = light.shadow.camera;
+			const texelWidth = ( shadowCam.right - shadowCam.left ) / this.shadowMapSize;
+			const texelHeight = ( shadowCam.top - shadowCam.bottom ) / this.shadowMapSize;
 			light.shadow.camera.updateMatrixWorld( true );
 			_cameraToLightMatrix.multiplyMatrices( light.shadow.camera.matrixWorldInverse, cameraMatrix );
 			frustums[ i ].toSpace( _cameraToLightMatrix, _lightSpaceFrustum );
 
-			// Get the two points that represent that furthest points on the frustum assuming
-			// that's either the diagonal across the far plane or the diagonal across the whole
-			// frustum itself.
 			const nearVerts = _lightSpaceFrustum.vertices.near;
 			const farVerts = _lightSpaceFrustum.vertices.far;
-			const point1 = farVerts[ 0 ];
-			let point2;
-			if ( point1.distanceTo( farVerts[ 2 ] ) > point1.distanceTo( nearVerts[ 2 ] ) ) {
-
-				point2 = farVerts[ 2 ];
-
-			} else {
-
-				point2 = nearVerts[ 2 ];
-
-			}
-
-			let squaredBBWidth = point1.distanceTo( point2 );
 			_bbox.makeEmpty();
 			for ( let j = 0; j < 4; j ++ ) {
 
@@ -196,30 +230,12 @@ export default class CSM {
 
 			}
 
-			if ( this.fade ) {
-
-				// expand the shadow extents by the fade margin if fade is enabled.
-				const camera = this.camera;
-				const far = Math.max( camera.far, this.maxFar );
-				const linearDepth = frustums[ i ].vertices.far[ 0 ].z / ( far - camera.near );
-				const margin = 0.25 * Math.pow( linearDepth, 2.0 ) * ( far - camera.near );
-
-				squaredBBWidth += margin;
-
-			}
-
-			const texelSize = squaredBBWidth / this.shadowMapSize;
 			_bbox.getCenter( _center );
 			_center.z = _bbox.max.z + this.lightMargin;
-			_center.x = Math.floor( _center.x / texelSize ) * texelSize;
-			_center.y = Math.floor( _center.y / texelSize ) * texelSize;
+			_center.x = Math.floor( _center.x / texelWidth ) * texelWidth;
+			_center.y = Math.floor( _center.y / texelHeight ) * texelHeight;
 			_center.applyMatrix4( light.shadow.camera.matrixWorld );
 
-			light.shadow.camera.left = - squaredBBWidth / 2;
-			light.shadow.camera.right = squaredBBWidth / 2;
-			light.shadow.camera.top = squaredBBWidth / 2;
-			light.shadow.camera.bottom = - squaredBBWidth / 2;
-
 			light.position.copy( _center );
 			light.target.position.copy( _center );
 
@@ -227,8 +243,8 @@ export default class CSM {
 			light.target.position.y += this.lightDirection.y;
 			light.target.position.z += this.lightDirection.z;
 
-			light.shadow.camera.updateProjectionMatrix();
 			light.shadow.camera.updateMatrixWorld();
+			light.shadow.camera.updateProjectionMatrix();
 
 		}
 
@@ -329,6 +345,7 @@ export default class CSM {
 
 		this.getBreaks();
 		this.initCascades();
+		this.updateShadowBounds();
 		this.updateUniforms();
 
 	}