ソースを参照

WebGPURenderer: Introduce `Node.updateAfter` (#28552)

Renaud Rohlinger 1 年間 前
コミット
f805325738

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

@@ -17,6 +17,7 @@ class Node extends EventDispatcher {
 
 		this.updateType = NodeUpdateType.NONE;
 		this.updateBeforeType = NodeUpdateType.NONE;
+		this.updateAfterType = NodeUpdateType.NONE;
 
 		this.uuid = MathUtils.generateUUID();
 
@@ -165,6 +166,12 @@ class Node extends EventDispatcher {
 
 	}
 
+	getUpdateAfterType() {
+
+		return this.updateAfterType;
+
+	}
+
 	getElementType( builder ) {
 
 		const type = this.getNodeType( builder );
@@ -273,6 +280,12 @@ class Node extends EventDispatcher {
 
 	}
 
+	updateAfter( /*frame*/ ) {
+
+		console.warn( 'Abstract function.' );
+
+	}
+
 	update( /*frame*/ ) {
 
 		console.warn( 'Abstract function.' );

+ 8 - 0
examples/jsm/nodes/core/NodeBuilder.js

@@ -67,6 +67,7 @@ class NodeBuilder {
 		this.nodes = [];
 		this.updateNodes = [];
 		this.updateBeforeNodes = [];
+		this.updateAfterNodes = [];
 		this.hashNodes = {};
 
 		this.lightsNode = null;
@@ -215,6 +216,7 @@ class NodeBuilder {
 
 			const updateType = node.getUpdateType();
 			const updateBeforeType = node.getUpdateBeforeType();
+			const updateAfterType = node.getUpdateAfterType();
 
 			if ( updateType !== NodeUpdateType.NONE ) {
 
@@ -228,6 +230,12 @@ class NodeBuilder {
 
 			}
 
+			if ( updateAfterType !== NodeUpdateType.NONE ) {
+
+				this.updateAfterNodes.push( node );
+
+			}
+
 		}
 
 	}

+ 42 - 0
examples/jsm/nodes/core/NodeFrame.js

@@ -14,6 +14,7 @@ class NodeFrame {
 
 		this.updateMap = new WeakMap();
 		this.updateBeforeMap = new WeakMap();
+		this.updateAfterMap = new WeakMap();
 
 		this.renderer = null;
 		this.material = null;
@@ -83,6 +84,47 @@ class NodeFrame {
 
 	}
 
+	updateAfterNode( node ) {
+
+		const updateType = node.getUpdateAfterType();
+		const reference = node.updateReference( this );
+
+		if ( updateType === NodeUpdateType.FRAME ) {
+
+			const { frameMap } = this._getMaps( this.updateAfterMap, reference );
+
+			if ( frameMap.get( reference ) !== this.frameId ) {
+
+				if ( node.updateAfter( this ) !== false ) {
+
+					frameMap.set( reference, this.frameId );
+
+				}
+
+			}
+
+		} else if ( updateType === NodeUpdateType.RENDER ) {
+
+			const { renderMap } = this._getMaps( this.updateAfterMap, reference );
+
+			if ( renderMap.get( reference ) !== this.renderId ) {
+
+				if ( node.updateAfter( this ) !== false ) {
+
+					renderMap.set( reference, this.renderId );
+
+				}
+
+			}
+
+		} else if ( updateType === NodeUpdateType.OBJECT ) {
+
+			node.updateAfter( this );
+
+		}
+
+	}
+
 	updateNode( node ) {
 
 		const updateType = node.getUpdateType();

+ 6 - 0
examples/jsm/renderers/common/Renderer.js

@@ -399,6 +399,8 @@ class Renderer {
 
 				this.backend.draw( renderObject, this.info );
 
+				this._nodes.updateAfter( renderObject );
+
 			}
 
 		}
@@ -1527,6 +1529,8 @@ class Renderer {
 
 		}
 
+		this._nodes.updateAfter( renderObject );
+
 	}
 
 	_createObjectPipeline( object, material, scene, camera, lightsNode, passId ) {
@@ -1545,6 +1549,8 @@ class Renderer {
 
 		this._pipelines.getForRender( renderObject, this._compilationPromises );
 
+		this._nodes.updateAfter( renderObject );
+
 	}
 
 	get compute() {

+ 2 - 1
examples/jsm/renderers/common/nodes/NodeBuilderState.js

@@ -1,6 +1,6 @@
 class NodeBuilderState {
 
-	constructor( vertexShader, fragmentShader, computeShader, nodeAttributes, bindings, updateNodes, updateBeforeNodes, transforms = [] ) {
+	constructor( vertexShader, fragmentShader, computeShader, nodeAttributes, bindings, updateNodes, updateBeforeNodes, updateAfterNodes, transforms = [] ) {
 
 		this.vertexShader = vertexShader;
 		this.fragmentShader = fragmentShader;
@@ -12,6 +12,7 @@ class NodeBuilderState {
 
 		this.updateNodes = updateNodes;
 		this.updateBeforeNodes = updateBeforeNodes;
+		this.updateAfterNodes = updateAfterNodes;
 
 		this.usedTimes = 0;
 

+ 14 - 0
examples/jsm/renderers/common/nodes/Nodes.js

@@ -182,6 +182,7 @@ class Nodes extends DataMap {
 			nodeBuilder.getBindings(),
 			nodeBuilder.updateNodes,
 			nodeBuilder.updateBeforeNodes,
+			nodeBuilder.updateAfterNodes,
 			nodeBuilder.transforms
 		);
 
@@ -427,6 +428,19 @@ class Nodes extends DataMap {
 
 	}
 
+	updateAfter( renderObject ) {
+
+		const nodeFrame = this.getNodeFrameForRender( renderObject );
+		const nodeBuilder = renderObject.getNodeBuilderState();
+
+		for ( const node of nodeBuilder.updateAfterNodes ) {
+
+			nodeFrame.updateAfterNode( node );
+
+		}
+
+	}
+
 	updateForCompute( computeNode ) {
 
 		const nodeFrame = this.getNodeFrame();