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

RenderObject: Introduce `getGeometryCacheKey()` (#29465)

* RenderObject: Added `getGeometryCacheKey()`

* NodeMaterialObserver: Improve skinnedmesh and morph supports

* cleanup
sunag 1 год назад
Родитель
Сommit
20ec73666b

+ 32 - 4
src/materials/nodes/manager/NodeMaterialObserver.js

@@ -57,6 +57,7 @@ class NodeMaterialObserver {
 
 		this.renderObjects = new WeakMap();
 		this.hasNode = this.containsNode( builder );
+		this.hasAnimation = builder.object.isSkinnedMesh === true;
 		this.refreshUniforms = refreshUniforms;
 		this.renderId = 0;
 
@@ -89,6 +90,12 @@ class NodeMaterialObserver {
 				worldMatrix: renderObject.object.matrixWorld.clone()
 			};
 
+			if ( renderObject.object.morphTargetInfluences ) {
+
+				data.morphTargetInfluences = renderObject.object.morphTargetInfluences.slice();
+
+			}
+
 			if ( renderObject.bundle !== null ) {
 
 				data.version = renderObject.bundle.version;
@@ -158,13 +165,15 @@ class NodeMaterialObserver {
 
 	equals( renderObject ) {
 
+		const { object, material } = renderObject;
+
 		const renderObjectData = this.getRenderObjectData( renderObject );
 
 		// world matrix
 
-		if ( renderObjectData.worldMatrix.equals( renderObject.object.matrixWorld ) !== true ) {
+		if ( renderObjectData.worldMatrix.equals( object.matrixWorld ) !== true ) {
 
-			renderObjectData.worldMatrix.copy( renderObject.object.matrixWorld );
+			renderObjectData.worldMatrix.copy( object.matrixWorld );
 
 			return false;
 
@@ -173,7 +182,6 @@ class NodeMaterialObserver {
 		// material
 
 		const materialData = renderObjectData.material;
-		const material = renderObject.material;
 
 		for ( const property in materialData ) {
 
@@ -211,6 +219,26 @@ class NodeMaterialObserver {
 
 		}
 
+		// morph targets
+
+		if ( renderObjectData.morphTargetInfluences ) {
+
+			let morphChanged = false;
+
+			for ( let i = 0; i < renderObjectData.morphTargetInfluences.length; i ++ ) {
+
+				if ( renderObjectData.morphTargetInfluences[ i ] !== object.morphTargetInfluences[ i ] ) {
+
+					morphChanged = true;
+
+				}
+
+			}
+
+			if ( morphChanged ) return true;
+
+		}
+
 		// bundle
 
 		if ( renderObject.bundle !== null ) {
@@ -225,7 +253,7 @@ class NodeMaterialObserver {
 
 	needsRefresh( renderObject, nodeFrame ) {
 
-		if ( this.hasNode || this.firstInitialization( renderObject ) )
+		if ( this.hasNode || this.hasAnimation || this.firstInitialization( renderObject ) )
 			return true;
 
 		const { renderId } = nodeFrame;

+ 30 - 1
src/renderers/common/RenderObject.js

@@ -248,6 +248,35 @@ export default class RenderObject {
 
 	}
 
+	getGeometryCacheKey() {
+
+		const { geometry } = this;
+
+		let cacheKey = '';
+
+		for ( const name of Object.keys( geometry.attributes ).sort() ) {
+
+			const attribute = geometry.attributes[ name ];
+
+			cacheKey += name + ',';
+
+			if ( attribute.data ) cacheKey += attribute.data.stride + ',';
+			if ( attribute.offset ) cacheKey += attribute.offset + ',';
+			if ( attribute.itemSize ) cacheKey += attribute.itemSize + ',';
+			if ( attribute.normalized ) cacheKey += 'n,';
+
+		}
+
+		if ( geometry.index ) {
+
+			cacheKey += 'index,';
+
+		}
+
+		return cacheKey;
+
+	}
+
 	getMaterialCacheKey() {
 
 		const { object, material } = this;
@@ -304,7 +333,7 @@ export default class RenderObject {
 
 		if ( object.geometry ) {
 
-			cacheKey += object.geometry.id + ',';
+			cacheKey += this.getGeometryCacheKey();
 
 		}
 

+ 0 - 1
src/renderers/webgpu/WebGPUBackend.js

@@ -1061,7 +1061,6 @@ class WebGPUBackend extends Backend {
 
 	}
 
-
 	// textures
 
 	createSampler( texture ) {

粤ICP备19079148号