readyPlayerMe avatars come with 63 facial morphTargets. Animating an expression on THREE.js requires tweening many of these simultaneously, e.g. surprise - “jawOpen”, “eyeWideLeft”, “eyeWideRight”, “browOuterUpLeft”…etc. This is cumbersome (especially with multiple avatars) and doesn’t work well as the number of morphTargets increases above 3.
Is there a way to create new morphTargets by merging those which ship with the avatar? i.e. create a 64th “surprise” morphTarget which equals “0.8 x jawOpen” + “0.5 X eyeWideLeft” + …etc.? Blender has a “New Shape From Mix” function that does exactly this.
Research so far has drawn a blank, and numerous attempts to manually add to morphAttributes have been unsuccessful. Any help would be much appreciated,
Finally figured it out. It’s a manual workaround but it does the job. Here’s the solution if anyone else is facing the same issue:
Create new Float32BufferAttributes for position and normal with one of the existing morphs which make up the desired new expression (e.g. 45 is “jawOpen” in this case"):
const newMorphTargetPosition = new THREE.Float32BufferAttribute( mesh.geometry.morphAttributes.position.array, 3 )
const newMorphTargetNormal = new THREE.Float32BufferAttribute( mesh.geometry.morphAttributes.position.array, 3 )
Add these to the morphAttributes arrays:
mesh.geometry.morphAttributes.position = [...mesh.geometry.morphAttributes.position, newMorphTargetPosition]
mesh.geometry.morphAttributes.normal = [...mesh.geometry.morphAttributes.normal, newMorphTargetNormal]
Give it a name and index:
mesh.morphTargetDictionary['surprise'] = 63
Append a value to morphTargetInfluences:
mesh.morphTargetInfluences = [...mesh.morphTargetInfluences, 0]
Now you can add other morphs on top by element-wise adding their position and normal arrays to this new morph
If anyone has a more elegant solution please let me know!