Преглед изворни кода

CSM: Avoid circular dependency in camera computations. (#25265)

* Avoid circular dependency in CSM camera computations

* Screenshot after the fix (artifact line disappeared)

* Simplify (remove _lightTarget)
Ondřej Španěl пре 2 година
родитељ
комит
565f878708
2 измењених фајлова са 11 додато и 3 уклоњено
  1. 11 3
      examples/jsm/csm/CSM.js
  2. BIN
      examples/screenshots/webgl_shadowmap_csm.jpg

+ 11 - 3
examples/jsm/csm/CSM.js

@@ -16,6 +16,9 @@ const _center = new Vector3();
 const _bbox = new Box3();
 const _uniformArray = [];
 const _logArray = [];
+const _lightOrientationMatrix = new Matrix4()
+const _lightOrientationMatrixInverse = new Matrix4()
+const _up = new Vector3( 0, 1, 0 );
 
 export class CSM {
 
@@ -200,14 +203,19 @@ export class CSM {
 
 		const camera = this.camera;
 		const frustums = this.frustums;
+
+		// for each frustum we need to find its min-max box aligned with the light orientation
+		// the position in _lightOrientationMatrix does not matter, as we transform there and back
+		_lightOrientationMatrix.lookAt( new Vector3(), this.lightDirection, _up );
+		_lightOrientationMatrixInverse.copy( _lightOrientationMatrix ).invert();
+
 		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, camera.matrixWorld );
+			_cameraToLightMatrix.multiplyMatrices( _lightOrientationMatrixInverse, camera.matrixWorld );
 			frustums[ i ].toSpace( _cameraToLightMatrix, _lightSpaceFrustum );
 
 			const nearVerts = _lightSpaceFrustum.vertices.near;
@@ -224,7 +232,7 @@ export class CSM {
 			_center.z = _bbox.max.z + this.lightMargin;
 			_center.x = Math.floor( _center.x / texelWidth ) * texelWidth;
 			_center.y = Math.floor( _center.y / texelHeight ) * texelHeight;
-			_center.applyMatrix4( light.shadow.camera.matrixWorld );
+			_center.applyMatrix4( _lightOrientationMatrix );
 
 			light.position.copy( _center );
 			light.target.position.copy( _center );

BIN
examples/screenshots/webgl_shadowmap_csm.jpg