Просмотр исходного кода

WebGPURenderer: Add cache for shadow nodes (#31880)

* add cache for shadow nodes

* Update Renderer.js

* revision

* Update Renderer.js

* revision

* cleanup
sunag 4 месяцев назад
Родитель
Сommit
aa3e118a67
1 измененных файлов с 118 добавлено и 70 удалено
  1. 118 70
      src/renderers/common/Renderer.js

+ 118 - 70
src/renderers/common/Renderer.js

@@ -624,6 +624,14 @@ class Renderer {
 		 */
 		this._colorBufferType = colorBufferType;
 
+		/**
+		 * A cache for shadow nodes per material
+		 *
+		 * @private
+		 * @type {WeakMap<Material, Object>}
+		 */
+		this._cacheShadowNodes = new WeakMap();
+
 		/**
 		 * Whether the renderer has been initialized or not.
 		 *
@@ -2860,6 +2868,93 @@ class Renderer {
 
 	}
 
+	/**
+	 * Retrieves shadow nodes for the given material. This is used to setup shadow passes.
+	 * The result is cached per material and updated when the material's version changes.
+	 *
+	 * @param {Material} material
+	 * @returns {Object} - The shadow nodes for the material.
+	 */
+	_getShadowNodes( material ) {
+
+		const version = material.version;
+
+		let cache = this._cacheShadowNodes.get( material );
+
+		if ( cache === undefined || cache.version !== version ) {
+
+			const hasMap = material.map !== null;
+			const hasColorNode = material.colorNode && material.colorNode.isNode;
+			const hasCastShadowNode = material.castShadowNode && material.castShadowNode.isNode;
+
+			let positionNode = null;
+			let colorNode = null;
+			let depthNode = null;
+
+			if ( hasMap || hasColorNode || hasCastShadowNode ) {
+
+				let shadowRGB;
+				let shadowAlpha;
+
+				if ( hasCastShadowNode ) {
+
+					shadowRGB = material.castShadowNode.rgb;
+					shadowAlpha = material.castShadowNode.a;
+
+				} else {
+
+					shadowRGB = vec3( 0 );
+					shadowAlpha = float( 1 );
+
+				}
+
+				if ( hasMap ) {
+
+					shadowAlpha = shadowAlpha.mul( reference( 'map', 'texture', material ).a );
+
+				}
+
+				if ( hasColorNode ) {
+
+					shadowAlpha = shadowAlpha.mul( material.colorNode.a );
+
+				}
+
+				colorNode = vec4( shadowRGB, shadowAlpha );
+
+			}
+
+			if ( material.depthNode && material.depthNode.isNode ) {
+
+				depthNode = material.depthNode;
+
+			}
+
+			if ( material.castShadowPositionNode && material.castShadowPositionNode.isNode ) {
+
+				positionNode = material.castShadowPositionNode;
+
+			} else if ( material.positionNode && material.positionNode.isNode ) {
+
+				positionNode = material.positionNode;
+
+			}
+
+			cache = {
+				version,
+				colorNode,
+				depthNode,
+				positionNode
+			};
+
+			this._cacheShadowNodes.set( material, cache );
+
+		}
+
+		return cache;
+
+	}
+
 	/**
 	 * This method represents the default render object function that manages the render lifecycle
 	 * of the object.
@@ -2876,9 +2971,11 @@ class Renderer {
 	 */
 	renderObject( object, scene, camera, geometry, material, group, lightsNode, clippingContext = null, passId = null ) {
 
-		let overridePositionNode;
-		let overrideColorNode;
-		let overrideDepthNode;
+		let materialOverride = false;
+		let materialColorNode;
+		let materialDepthNode;
+		let materialPositionNode;
+		let materialSide;
 
 		//
 
@@ -2890,9 +2987,16 @@ class Renderer {
 
 			const overrideMaterial = scene.overrideMaterial;
 
+			materialOverride = true;
+
+			// store original nodes
+			materialColorNode = scene.overrideMaterial.colorNode;
+			materialDepthNode = scene.overrideMaterial.depthNode;
+			materialPositionNode = scene.overrideMaterial.positionNode;
+			materialSide = scene.overrideMaterial.side;
+
 			if ( material.positionNode && material.positionNode.isNode ) {
 
-				overridePositionNode = overrideMaterial.positionNode;
 				overrideMaterial.positionNode = material.positionNode;
 
 			}
@@ -2903,60 +3007,13 @@ class Renderer {
 
 			if ( overrideMaterial.isShadowPassMaterial ) {
 
-				overrideMaterial.side = material.shadowSide === null ? material.side : material.shadowSide;
-
-				const hasMap = material.map !== null;
-				const hasColorNode = material.colorNode && material.colorNode.isNode;
-				const hasCastShadowNode = material.castShadowNode && material.castShadowNode.isNode;
-
-				if ( hasMap || hasColorNode || hasCastShadowNode ) {
-
-					overrideColorNode = overrideMaterial.colorNode;
-
-					let shadowRGB;
-					let shadowAlpha;
-
-					if ( hasCastShadowNode ) {
-
-						shadowRGB = material.castShadowNode.rgb;
-						shadowAlpha = material.castShadowNode.a;
-
-					} else {
-
-						shadowRGB = vec3( 0 );
-						shadowAlpha = float( 1 );
-
-					}
-
-					if ( hasMap ) {
-
-						shadowAlpha = shadowAlpha.mul( reference( 'map', 'texture', material ).a );
-
-					}
+				const { colorNode, depthNode, positionNode } = this._getShadowNodes( material );
 
-					if ( hasColorNode ) {
-
-						shadowAlpha = shadowAlpha.mul( material.colorNode.a );
-
-					}
-
-					overrideMaterial.colorNode = vec4( shadowRGB, shadowAlpha );
-
-				}
-
-				if ( material.depthNode && material.depthNode.isNode ) {
-
-					overrideDepthNode = overrideMaterial.depthNode;
-					overrideMaterial.depthNode = material.depthNode;
-
-				}
-
-				if ( material.castShadowPositionNode && material.castShadowPositionNode.isNode ) {
-
-					overridePositionNode = overrideMaterial.positionNode;
-					overrideMaterial.positionNode = material.castShadowPositionNode;
+				overrideMaterial.side = material.shadowSide === null ? material.side : material.shadowSide;
 
-				}
+				if ( colorNode !== null ) overrideMaterial.colorNode = colorNode;
+				if ( depthNode !== null ) overrideMaterial.depthNode = depthNode;
+				if ( positionNode !== null ) overrideMaterial.positionNode = positionNode;
 
 			}
 
@@ -2984,21 +3041,12 @@ class Renderer {
 
 		//
 
-		if ( overridePositionNode !== undefined ) {
-
-			scene.overrideMaterial.positionNode = overridePositionNode;
-
-		}
-
-		if ( overrideDepthNode !== undefined ) {
-
-			scene.overrideMaterial.depthNode = overrideDepthNode;
-
-		}
-
-		if ( overrideColorNode !== undefined ) {
+		if ( materialOverride ) {
 
-			scene.overrideMaterial.colorNode = overrideColorNode;
+			scene.overrideMaterial.colorNode = materialColorNode;
+			scene.overrideMaterial.depthNode = materialDepthNode;
+			scene.overrideMaterial.positionNode = materialPositionNode;
+			scene.overrideMaterial.side = materialSide;
 
 		}
 

粤ICP备19079148号