Browse Source

WebGPURenderer: Update attribute only when needed (#28701)

* update attribute only when necessary

* fix interleavedbuffers

* fixing attribute updates might have changed puppeteer?

* support instanceMatrix.needsUpdate

* cleanup

* instanceColor can be undefined
Renaud Rohlinger 1 year ago
parent
commit
a83652d2b5

+ 24 - 0
examples/jsm/nodes/accessors/InstanceNode.js

@@ -5,6 +5,7 @@ import { normalLocal } from './NormalNode.js';
 import { positionLocal } from './PositionNode.js';
 import { nodeProxy, vec3, mat3, mat4 } from '../shadernode/ShaderNode.js';
 import { DynamicDrawUsage, InstancedInterleavedBuffer, InstancedBufferAttribute } from 'three';
+import { NodeUpdateType } from '../core/constants.js';
 
 class InstanceNode extends Node {
 
@@ -18,6 +19,11 @@ class InstanceNode extends Node {
 
 		this.instanceColorNode = null;
 
+		this.updateType = NodeUpdateType.FRAME;
+
+		this.buffer = null;
+		this.bufferColor = null;
+
 	}
 
 	setup( /*builder*/ ) {
@@ -31,6 +37,7 @@ class InstanceNode extends Node {
 			const instanceAttribute = instanceMesh.instanceMatrix;
 			const buffer = new InstancedInterleavedBuffer( instanceAttribute.array, 16, 1 );
 
+			this.buffer = buffer;
 			const bufferFn = instanceAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
 
 			const instanceBuffers = [
@@ -54,6 +61,7 @@ class InstanceNode extends Node {
 			const buffer = new InstancedBufferAttribute( instanceColorAttribute.array, 3 );
 			const bufferFn = instanceColorAttribute.usage === DynamicDrawUsage ? instancedDynamicBufferAttribute : instancedBufferAttribute;
 
+			this.bufferColor = buffer;
 			this.instanceColorNode = vec3( bufferFn( buffer, 'vec3', 3, 0 ) );
 
 		}
@@ -85,6 +93,22 @@ class InstanceNode extends Node {
 
 	}
 
+	update( /*frame*/ ) {
+
+		if ( this.instanceMesh.instanceMatrix.version !== this.buffer.version ) {
+
+			this.buffer.version = this.instanceMesh.instanceMatrix.version;
+
+		}
+
+		if ( this.instanceMesh.instanceColor && this.instanceMesh.instanceColor.version !== this.bufferColor.version ) {
+
+			this.bufferColor.version = this.instanceMesh.instanceColor.version;
+
+		}
+
+	}
+
 }
 
 export default InstanceNode;

+ 4 - 4
examples/jsm/renderers/common/Geometries.js

@@ -76,7 +76,7 @@ class Geometries extends DataMap {
 		this.info = info;
 
 		this.wireframes = new WeakMap();
-		this.attributeCall = new WeakMap();
+		this.attributeVersion = new WeakMap();
 
 	}
 
@@ -170,13 +170,13 @@ class Geometries extends DataMap {
 
 	updateAttribute( attribute, type ) {
 
-		const callId = this.info.render.calls;
+		const attributeData = attribute.isInterleavedBufferAttribute ? attribute.data : attribute;
 
-		if ( this.attributeCall.get( attribute ) !== callId ) {
+		if ( this.attributeVersion.get( attribute ) !== attributeData.version ) {
 
 			this.attributes.update( attribute, type );
 
-			this.attributeCall.set( attribute, callId );
+			this.attributeVersion.set( attribute, attributeData.version );
 
 		}
 

BIN
examples/screenshots/webgpu_instance_mesh.jpg


+ 2 - 0
examples/webgpu_instance_mesh.html

@@ -155,6 +155,8 @@
 
 					}
 
+					mesh.instanceMatrix.needsUpdate = true;
+			
 				}
 
 				await renderer.render( scene, camera );