Browse Source

use projection matrix in frustum

Garrett Johnson 5 năm trước cách đây
mục cha
commit
9fcb357600
2 tập tin đã thay đổi với 30 bổ sung21 xóa
  1. 2 1
      examples/jsm/csm/CSM.js
  2. 28 20
      examples/jsm/csm/Frustum.js

+ 2 - 1
examples/jsm/csm/CSM.js

@@ -72,6 +72,7 @@ export default class CSM {
 
 	initCascades() {
 
+		// TODO: Handle orthographic camera
 		const camera = this.camera;
 		const far = Math.min(camera.far, this.maxFar);
 		this.mainFrustum = new Frustum( {
@@ -239,7 +240,7 @@ export default class CSM {
 	updateUniforms() {
 
 		const far = Math.min(this.camera.far, this.maxFar);
-		console.log('HERE', far);
+
 		for ( let i = 0; i < this.materials.length; i ++ ) {
 
 			this.materials[ i ].uniforms.CSM_cascades.value = this.getExtendedBreaks();

+ 28 - 20
examples/jsm/csm/Frustum.js

@@ -2,19 +2,19 @@
  * @author vHawk / https://github.com/vHawk/
  */
 
-import { MathUtils, Vector3 } from '../../../build/three.module.js';
+import { MathUtils, Vector3, Matrix4 } from '../../../build/three.module.js';
 import FrustumVertex from './FrustumVertex.js';
 
+const inverseProjectionMatrix = new Matrix4();
+
 export default class Frustum {
 
 	constructor( data ) {
 
 		data = data || {};
 
-		this.fov = data.fov || 70;
-		this.near = data.near || 0.1;
-		this.far = data.far || 1000;
-		this.aspect = data.aspect || 1;
+		this.projectionMatrix = data.projectionMatrix;
+		this.maxFar = data.maxFar || 10000;
 
 		this.vertices = {
 			near: [],
@@ -25,29 +25,37 @@ export default class Frustum {
 
 	getViewSpaceVertices() {
 
-		this.nearPlaneY = this.near * Math.tan( MathUtils.degToRad( this.fov / 2 ) );
-		this.nearPlaneX = this.aspect * this.nearPlaneY;
-
-		this.farPlaneY = this.far * Math.tan( MathUtils.degToRad( this.fov / 2 ) );
-		this.farPlaneX = this.aspect * this.farPlaneY;
+		const maxFar = this.maxFar;
+		inverseProjectionMatrix.getInverse( this.projectionMatrix );
 
 		// 3 --- 0  vertices.near/far order
 		// |     |
 		// 2 --- 1
+		// clip space spans from [-1, 1]
 
 		this.vertices.near.push(
-			new FrustumVertex( this.nearPlaneX, this.nearPlaneY, - this.near ),
-			new FrustumVertex( this.nearPlaneX, - this.nearPlaneY, - this.near ),
-			new FrustumVertex( - this.nearPlaneX, - this.nearPlaneY, - this.near ),
-			new FrustumVertex( - this.nearPlaneX, this.nearPlaneY, - this.near )
-		);
+			new Vector3( 1, 1, - 1 ),
+			new Vector3( 1, - 1, - 1 ),
+			new Vector3( - 1, - 1, - 1 ),
+			new Vector3( - 1, 1, - 1 )
+		).forEach( function( v ) {
+
+			v.applyMatrix4( inverseProjectionMatrix );
+			v.multiplyScalar( Math.min( v.z / maxFar, 1.0 ) );
+
+		} );
 
 		this.vertices.far.push(
-			new FrustumVertex( this.farPlaneX, this.farPlaneY, - this.far ),
-			new FrustumVertex( this.farPlaneX, - this.farPlaneY, - this.far ),
-			new FrustumVertex( - this.farPlaneX, - this.farPlaneY, - this.far ),
-			new FrustumVertex( - this.farPlaneX, this.farPlaneY, - this.far )
-		);
+			new Vector3( 1, 1, 1 ),
+			new Vector3( 1, - 1, 1 ),
+			new Vector3( - 1, - 1, 1 ),
+			new Vector3( - 1, 1, 1 )
+		).forEach( function( v ) {
+
+			v.applyMatrix4( inverseProjectionMatrix );
+			v.multiplyScalar( Math.min( v.z / maxFar, 1.0 ) );
+
+		} );
 
 		return this.vertices;