Răsfoiți Sursa

Morph: Fix individual `morphTargetInfluences` per object (#33772)

sunag 2 zile în urmă
părinte
comite
a02cfd2265
1 a modificat fișierele cu 42 adăugiri și 27 ștergeri
  1. 42 27
      src/nodes/accessors/Morph.js

+ 42 - 27
src/nodes/accessors/Morph.js

@@ -1,6 +1,5 @@
 
 import { float, Fn, ivec2, int, If, uniform } from '../tsl/TSLBase.js';
-import { reference } from './ReferenceNode.js';
 import { Loop } from '../utils/LoopNode.js';
 import { OnObjectUpdate } from '../utils/EventNode.js';
 import { textureLoad } from './TextureNode.js';
@@ -12,10 +11,11 @@ import { DataArrayTexture } from '../../textures/DataArrayTexture.js';
 import { Vector2 } from '../../math/Vector2.js';
 import { Vector4 } from '../../math/Vector4.js';
 import { FloatType } from '../../constants.js';
+import { uniformArray } from './UniformArrayNode.js';
 
 const _morphTextures = /*@__PURE__*/ new WeakMap();
 const _morphVec4 = /*@__PURE__*/ new Vector4();
-const _morphBaseInfluences = /*@__PURE__*/ new WeakMap();
+const _morphInfluencesData = /*@__PURE__*/ new WeakMap();
 
 /**
  * TSL function that retrieves and scales the morphed attribute (position or normal) texel value.
@@ -174,13 +174,6 @@ function getEntry( geometry ) {
 
 }
 
-/**
- * TSL object representing a reference to the mesh's morphTargetInfluences array.
- *
- * @type {ReferenceNode<float>}
- */
-export const morphTargetInfluences = /*@__PURE__*/ reference( 'morphTargetInfluences', 'float' );
-
 /**
  * TSL function representing the vertex shader morph targets blend setup.
  * Dynamically computes morph targets weights and updates positionLocal and normalLocal in-place.
@@ -201,33 +194,30 @@ export const morphReference = /*@__PURE__*/ Fn( ( [ mesh ] ) => {
 
 	if ( morphTargetsCount === 0 ) return;
 
-	let morphBaseInfluence = _morphBaseInfluences.get( mesh );
-
-	if ( ! morphBaseInfluence ) {
-
-		morphBaseInfluence = uniform( 1 );
-		_morphBaseInfluences.set( mesh, morphBaseInfluence );
-
-		OnObjectUpdate( ( { object } ) => {
+	// Init
 
-			if ( object.geometry.morphTargetsRelative ) {
+	let morphInfluenceData = _morphInfluencesData.get( mesh );
 
-				morphBaseInfluence.value = 1;
+	if ( morphInfluenceData === undefined || morphInfluenceData.count !== morphTargetsCount ) {
 
-			} else {
+		morphInfluenceData = {
+			base: uniform( 1 ),
+			influences: mesh.morphTargetInfluences ? uniformArray( mesh.morphTargetInfluences, 'float' ) : null,
+			count: morphTargetsCount
+		};
 
-				morphBaseInfluence.value = 1 - object.morphTargetInfluences.reduce( ( a, b ) => a + b, 0 );
+		_morphInfluencesData.set( mesh, morphInfluenceData );
 
-			}
+	}
 
-		} );
+	const { base, influences } = morphInfluenceData;
 
-	}
+	// Shader
 
 	const { texture: bufferMap, stride, size } = getEntry( geometry );
 
-	if ( hasMorphPosition === true ) positionLocal.mulAssign( morphBaseInfluence );
-	if ( hasMorphNormals === true ) normalLocal.mulAssign( morphBaseInfluence );
+	if ( hasMorphPosition === true ) positionLocal.mulAssign( base );
+	if ( hasMorphNormals === true ) normalLocal.mulAssign( base );
 
 	const width = int( size.width );
 
@@ -241,7 +231,7 @@ export const morphReference = /*@__PURE__*/ Fn( ( [ mesh ] ) => {
 
 		} else {
 
-			influence.assign( morphTargetInfluences.element( i ).toVar() );
+			influence.assign( influences.element( i ).toVar() );
 
 		}
 
@@ -277,6 +267,31 @@ export const morphReference = /*@__PURE__*/ Fn( ( [ mesh ] ) => {
 
 	} );
 
+	// Update
+
+	OnObjectUpdate( ( { object } ) => {
+
+		const { base, influences } = morphInfluenceData;
+
+		if ( object.geometry.morphTargetsRelative ) {
+
+			base.value = 1;
+
+		} else {
+
+			base.value = 1 - object.morphTargetInfluences.reduce( ( a, b ) => a + b, 0 );
+
+		}
+
+		if ( influences ) {
+
+			influences.array = object.morphTargetInfluences;
+			influences.update();
+
+		}
+
+	} );
+
 }, 'void' );
 
 

粤ICP备19079148号