Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 42 additions & 27 deletions src/nodes/accessors/Morph.js
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -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 );

Expand All @@ -241,7 +231,7 @@ export const morphReference = /*@__PURE__*/ Fn( ( [ mesh ] ) => {

} else {

influence.assign( morphTargetInfluences.element( i ).toVar() );
influence.assign( influences.element( i ).toVar() );

}

Expand Down Expand Up @@ -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' );


1 change: 1 addition & 0 deletions src/nodes/accessors/ReferenceNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ class ReferenceNode extends Node {
} else if ( Array.isArray( this.getValueFromReference() ) ) {

node = uniformArray( null, uniformType );
node.updateType = NodeUpdateType.OBJECT;

} else if ( uniformType === 'texture' ) {

Expand Down
2 changes: 1 addition & 1 deletion src/renderers/common/RenderObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ class RenderObject {

}

if ( object.isInstancedMesh || object.count > 1 || Array.isArray( object.morphTargetInfluences ) ) {
if ( object.isInstancedMesh || object.count > 1 ) {

// TODO: https://github.com/mrdoob/three.js/pull/29066#issuecomment-2269400850

Expand Down