Sfoglia il codice sorgente

WebGPURenderer: Fix lights hash (#27150)

sunag 1 anno fa
parent
commit
8e66fe5de4

+ 1 - 1
examples/jsm/nodes/Nodes.js

@@ -136,7 +136,7 @@ export { default as DirectionalLightNode } from './lighting/DirectionalLightNode
 export { default as SpotLightNode } from './lighting/SpotLightNode.js';
 export { default as IESSpotLightNode } from './lighting/IESSpotLightNode.js';
 export { default as AmbientLightNode } from './lighting/AmbientLightNode.js';
-export { default as LightsNode, lights, lightsWithoutWrap, addLightNode } from './lighting/LightsNode.js';
+export { default as LightsNode, lights, lightNodes, addLightNode } from './lighting/LightsNode.js';
 export { default as LightingNode /* @TODO: lighting (abstract), light */ } from './lighting/LightingNode.js';
 export { default as LightingContextNode, lightingContext } from './lighting/LightingContextNode.js';
 export { default as HemisphereLightNode } from './lighting/HemisphereLightNode.js';

+ 0 - 2
examples/jsm/nodes/core/Node.js

@@ -54,8 +54,6 @@ class Node extends EventDispatcher {
 
 	* getChildren() {
 
-		const self = this;
-
 		for ( const { childNode } of getNodeChildren( this ) ) {
 
 			yield childNode;

+ 3 - 7
examples/jsm/nodes/core/NodeUtils.js

@@ -6,17 +6,13 @@ export function getCacheKey( object ) {
 
 	if ( object.isNode === true ) {
 
-		cacheKey += `uuid:"${ object.uuid }"`;
+		cacheKey += object.id;
 
 	}
 
-	for ( const { property, index, childNode } of getNodeChildren( object ) ) {
+	for ( const { property, childNode } of getNodeChildren( object ) ) {
 
-		// @TODO: Think about implement NodeArray and NodeObject.
-
-		let childCacheKey = getCacheKey( childNode );
-		if ( ! childCacheKey.includes( ',' ) ) childCacheKey = childCacheKey.slice( childCacheKey.indexOf( '"' ), childCacheKey.indexOf( '}' ) );
-		cacheKey += `,${ property }${ index !== undefined ? '/' + index : '' }:${ childCacheKey }`;
+		cacheKey += ',' + property.slice( 0, - 4 ) + ':' + childNode.getCacheKey();
 
 	}
 

+ 27 - 3
examples/jsm/nodes/lighting/AnalyticLightNode.js

@@ -28,11 +28,21 @@ class AnalyticLightNode extends LightingNode {
 		this.shadowNode = null;
 
 		this.color = new Color();
-		this.colorNode = uniform( this.color );
+		this._defaultColorNode = uniform( this.color );
+
+		this.colorNode = this._defaultColorNode;
+
+		this.isAnalyticLightNode = true;
+
+	}
+
+	getCacheKey() {
+
+		return super.getCacheKey() + '-' + ( this.light.id + '-' + ( this.light.castShadow ? '1' : '0' ) );
 
 	}
 
-	getHash( /*builder*/ ) {
+	getHash() {
 
 		return this.light.uuid;
 
@@ -148,6 +158,7 @@ class AnalyticLightNode extends LightingNode {
 	setup( builder ) {
 
 		if ( this.light.castShadow ) this.setupShadow( builder );
+		else if ( this.shadowNode !== null ) this.disposeShadow();
 
 	}
 
@@ -156,6 +167,8 @@ class AnalyticLightNode extends LightingNode {
 		const { rtt, light } = this;
 		const { renderer, scene } = frame;
 
+		const currentOverrideMaterial = scene.overrideMaterial;
+
 		scene.overrideMaterial = depthMaterial;
 
 		rtt.setSize( light.shadow.mapSize.width, light.shadow.mapSize.height );
@@ -182,7 +195,18 @@ class AnalyticLightNode extends LightingNode {
 		renderer.setRenderTarget( currentRenderTarget );
 		renderer.setRenderObjectFunction( currentRenderObjectFunction );
 
-		scene.overrideMaterial = null;
+		scene.overrideMaterial = currentOverrideMaterial;
+
+	}
+
+	disposeShadow() {
+
+		this.rtt.dispose();
+
+		this.shadowNode = null;
+		this.rtt = null;
+
+		this.colorNode = this._defaultColorNode;
 
 	}
 

+ 27 - 31
examples/jsm/nodes/lighting/LightsNode.js

@@ -33,6 +33,26 @@ class LightsNode extends Node {
 
 	}
 
+	getHash() {
+
+		if ( this._hash === null ) {
+
+			const hash = [];
+
+			for ( const lightNode of this.lightNodes ) {
+
+				hash.push( lightNode.getHash() );
+
+			}
+
+			this._hash = 'lights-' + hash.join( ',' );
+
+		}
+
+		return this._hash;
+
+	}
+
 	setup( builder ) {
 
 		const context = builder.context;
@@ -57,7 +77,7 @@ class LightsNode extends Node {
 			for ( const lightNode of lightNodes ) {
 
 				lightNode.build( builder );
-	
+
 			}
 
 			//
@@ -76,7 +96,7 @@ class LightsNode extends Node {
 			if ( backdrop !== null ) {
 
 				totalDiffuse = vec3( backdropAlpha !== null ? backdropAlpha.mix( totalDiffuse, backdrop ) : backdrop );
-	
+
 			}
 
 			totalDiffuseNode.assign( totalDiffuse );
@@ -98,35 +118,11 @@ class LightsNode extends Node {
 
 	}
 
-	getHash( builder ) {
-
-		if ( this._hash === null ) {
-
-			let hash = '';
-
-			const lightNodes = this.lightNodes;
-
-			for ( const lightNode of lightNodes ) {
-
-				hash += lightNode.getHash( builder ) + ' ';
-
-			}
-
-			this._hash = hash;
-
-		}
-
-		return this._hash;
-
-	}
-
-	getLightNodeByHash( hash ) {
-
-		const lightNodes = this.lightNodes;
+	_getLightNodeById( id ) {
 
-		for ( const lightNode of lightNodes ) {
+		for ( const lightNode of this.lightNodes ) {
 
-			if ( lightNode.light.uuid === hash ) {
+			if ( lightNode.isAnalyticLightNode && lightNode.light.id === id ) {
 
 				return lightNode;
 
@@ -146,7 +142,7 @@ class LightsNode extends Node {
 
 		for ( const light of lights ) {
 
-			let lightNode = this.getLightNodeByHash( light.uuid );
+			let lightNode = this._getLightNodeById( light.id );
 
 			if ( lightNode === null ) {
 
@@ -173,7 +169,7 @@ class LightsNode extends Node {
 export default LightsNode;
 
 export const lights = ( lights ) => nodeObject( new LightsNode().fromLights( lights ) );
-export const lightsWithoutWrap = nodeProxy( LightsNode );
+export const lightNodes = nodeProxy( LightsNode );
 
 export function addLightNode( lightClass, lightNodeClass ) {
 

+ 2 - 2
examples/jsm/nodes/materials/NodeMaterial.js

@@ -11,7 +11,7 @@ import { skinning } from '../accessors/SkinningNode.js';
 import { morph } from '../accessors/MorphNode.js';
 import { texture } from '../accessors/TextureNode.js';
 import { cubeTexture } from '../accessors/CubeTextureNode.js';
-import { lightsWithoutWrap } from '../lighting/LightsNode.js';
+import { lightNodes } from '../lighting/LightsNode.js';
 import { mix } from '../math/MathNode.js';
 import { float, vec3, vec4 } from '../shadernode/ShaderNode.js';
 import AONode from '../lighting/AONode.js';
@@ -257,7 +257,7 @@ class NodeMaterial extends ShaderMaterial {
 
 		if ( materialLightsNode.length > 0 ) {
 
-			lightsNode = lightsWithoutWrap( [ ...lightsNode.lightNodes, ...materialLightsNode ] );
+			lightsNode = lightNodes( [ ...lightsNode.lightNodes, ...materialLightsNode ] );
 
 		}
 

+ 4 - 2
examples/jsm/renderers/common/RenderObjects.js

@@ -33,14 +33,16 @@ class RenderObjects {
 
 			if ( renderObject.version !== material.version || renderObject.needsUpdate ) {
 
-				renderObject.version = material.version;
-
 				if ( renderObject.initialCacheKey !== renderObject.getCacheKey() ) {
 
 					renderObject.dispose();
 
 					renderObject = this.get( object, material, scene, camera, lightsNode, renderContext, passId );
 
+				} else {
+
+					renderObject.version = material.version;
+
 				}
 
 			}