Browse Source

ShadowBaseNode: Fix CSM `shadowWorldPosition` (#30060)

sunag 1 năm trước cách đây
mục cha
commit
f5f25c3e9b

+ 11 - 8
examples/jsm/csm/CSMShadowNode.js

@@ -6,8 +6,7 @@ import {
 	Box3,
 	Object3D,
 	WebGLCoordinateSystem,
-	NodeUpdateType,
-	Node
+	ShadowBaseNode
 } from 'three/webgpu';
 
 import { CSMFrustum } from './CSMFrustum.js';
@@ -36,13 +35,12 @@ class LwLight extends Object3D {
 
 }
 
-class CSMShadowNode extends Node {
+class CSMShadowNode extends ShadowBaseNode {
 
 	constructor( light, data = {} ) {
 
-		super();
+		super( light );
 
-		this.light = light;
 		this.camera = null;
 		this.cascades = data.cascades || 3;
 		this.maxFar = data.maxFar || 100000;
@@ -57,7 +55,6 @@ class CSMShadowNode extends Node {
 		this._cascades = [];
 		this.mainFrustum = null;
 		this.frustums = [];
-		this.updateBeforeType = NodeUpdateType.FRAME;
 
 		this.lights = [];
 
@@ -264,7 +261,9 @@ class CSMShadowNode extends Node {
 		const linearDepth = viewZToOrthographicDepth( positionView.z, cameraNear, shadowFar ).toVar( 'linearDepth' );
 		const lastCascade = this.cascades - 1;
 
-		return Fn( () => {
+		return Fn( ( builder ) => {
+
+			this.setupShadowPosition( builder );
 
 			const ret = vec4( 1, 1, 1, 1 ).toVar( 'shadowValue' );
 
@@ -337,7 +336,9 @@ class CSMShadowNode extends Node {
 
 		const linearDepth = viewZToOrthographicDepth( positionView.z, cameraNear, shadowFar ).toVar( 'linearDepth' );
 
-		return Fn( () => {
+		return Fn( ( builder ) => {
+
+			this.setupShadowPosition( builder );
 
 			const ret = vec4( 1, 1, 1, 1 ).toVar( 'shadowValue' );
 			const cascade = vec2().toVar( 'cascade' );
@@ -430,6 +431,8 @@ class CSMShadowNode extends Node {
 
 		}
 
+		super.dispose();
+
 	}
 
 }

+ 1 - 0
src/Three.TSL.js

@@ -407,6 +407,7 @@ export const select = TSL.select;
 export const setCurrentStack = TSL.setCurrentStack;
 export const shaderStages = TSL.shaderStages;
 export const shadow = TSL.shadow;
+export const shadowWorldPosition = TSL.shadowWorldPosition;
 export const sharedUniformGroup = TSL.sharedUniformGroup;
 export const sheen = TSL.sheen;
 export const sheenRoughness = TSL.sheenRoughness;

+ 1 - 0
src/nodes/Nodes.js

@@ -132,6 +132,7 @@ export { default as BasicEnvironmentNode } from './lighting/BasicEnvironmentNode
 export { default as IrradianceNode } from './lighting/IrradianceNode.js';
 export { default as AONode } from './lighting/AONode.js';
 export { default as AnalyticLightNode } from './lighting/AnalyticLightNode.js';
+export { default as ShadowBaseNode } from './lighting/ShadowBaseNode.js';
 export { default as ShadowNode } from './lighting/ShadowNode.js';
 
 // pmrem

+ 43 - 0
src/nodes/lighting/ShadowBaseNode.js

@@ -0,0 +1,43 @@
+import Node from '../core/Node.js';
+import { NodeUpdateType } from '../core/constants.js';
+import { vec3 } from '../tsl/TSLBase.js';
+import { positionWorld } from '../accessors/Position.js';
+
+class ShadowBaseNode extends Node {
+
+	static get type() {
+
+		return 'ShadowBaseNode';
+
+	}
+
+	constructor( light ) {
+
+		super();
+
+		this.light = light;
+		this.updateBeforeType = NodeUpdateType.RENDER;
+
+		this.isShadowBaseNode = true;
+
+	}
+
+	setupShadowPosition( { material } ) {
+
+		// Use assign inside an Fn()
+
+		shadowWorldPosition.assign( material.shadowPositionNode || positionWorld );
+
+	}
+
+	dispose() {
+
+		this.updateBeforeType = NodeUpdateType.NONE;
+
+	}
+
+}
+
+export const shadowWorldPosition = /*@__PURE__*/ vec3().toVar( 'shadowWorldPosition' );
+
+export default ShadowBaseNode;

+ 7 - 12
src/nodes/lighting/ShadowNode.js

@@ -1,5 +1,4 @@
-import Node from '../core/Node.js';
-import { NodeUpdateType } from '../core/constants.js';
+import ShadowBaseNode, { shadowWorldPosition } from './ShadowBaseNode.js';
 import { float, vec2, vec3, vec4, If, int, Fn, nodeObject } from '../tsl/TSLBase.js';
 import { reference } from '../accessors/ReferenceNode.js';
 import { texture } from '../accessors/TextureNode.js';
@@ -19,8 +18,6 @@ import { objectPosition } from '../accessors/Object3DNode.js';
 import { lightShadowMatrix } from '../accessors/Lights.js';
 
 const shadowMaterialLib = /*@__PURE__*/ new WeakMap();
-const shadowWorldPosition = /*@__PURE__*/ vec3().toVar( 'shadowWorldPosition' );
-
 const linearDistance = /*@__PURE__*/ Fn( ( [ position, cameraNear, cameraFar ] ) => {
 
 	let dist = positionWorld.sub( position ).length();
@@ -250,7 +247,7 @@ const _shadowFilterLib = [ BasicShadowFilter, PCFShadowFilter, PCFSoftShadowFilt
 
 const _quadMesh = /*@__PURE__*/ new QuadMesh();
 
-class ShadowNode extends Node {
+class ShadowNode extends ShadowBaseNode {
 
 	static get type() {
 
@@ -260,9 +257,8 @@ class ShadowNode extends Node {
 
 	constructor( light, shadow = null ) {
 
-		super();
+		super( light );
 
-		this.light = light;
 		this.shadow = shadow || light.shadow;
 
 		this.shadowMap = null;
@@ -273,7 +269,6 @@ class ShadowNode extends Node {
 		this.vsmMaterialVertical = null;
 		this.vsmMaterialHorizontal = null;
 
-		this.updateBeforeType = NodeUpdateType.RENDER;
 		this._node = null;
 
 		this.isShadowNode = true;
@@ -425,12 +420,12 @@ class ShadowNode extends Node {
 
 		if ( builder.renderer.shadowMap.enabled === false ) return;
 
-		return Fn( ( { material } ) => {
-
-			shadowWorldPosition.assign( material.shadowPositionNode || positionWorld );
+		return Fn( () => {
 
 			let node = this._node;
 
+			this.setupShadowPosition( builder );
+
 			if ( node === null ) {
 
 				this._node = node = this.setupShadow( builder );
@@ -566,7 +561,7 @@ class ShadowNode extends Node {
 
 		}
 
-		this.updateBeforeType = NodeUpdateType.NONE;
+		super.dispose();
 
 	}
 

粤ICP备19079148号