Implemented it so far, instanced skinned mesh with individual animation states, also with the LOD system in-built to not only use a reduced geometry but also reduced set of bones.
The strategy is that instances are usually not all in front of the camera, so most likely fall into the lower LOD depending on the distance you set for them, generally it’s about keeping uploads of bone matrices small as possible asides of reducing animation computations.
Still need to test through the LOD part further and see how far i can reduce animations without core modifications, but they could be already throttled by the LOD using the onUpdate
callback to update your animation mixer.
The general idea is that each instance only uses 1 Mixer for each LOD, so the reduced bones are remapping the skin weights to parents for those bones not used in the LOD. Otherwise you would obviously need 3 Mixer for 3 LODs.
The other benefit is you can attach things and items as you would usually regardless of the LOD. And you can unlink it from the instancer anytime so it will render as regular SkinnedMesh again.
So far the API looks like (for 1 LOD)
const mixers = new WeakMap;
// Creates a instancer for this type of asset, you don't use the original of the glTF in the scene but make clones from it
instancer = new SkinnedInstancer({
target: playerMesh,
maxCount: 1024,
levels: [
{
distance: Infinity
}
],
onUpdate: ( instance, delta ) => mixers.get( instance ).update( delta )
});
scene.add( instancer );
// Clones the mesh and it's skeleton appropriately and
// calls instancer.link( mesh ) to render it through the instancer, but you
// still add and use the clone as usually in the scene.
const player = instancer.cloneLink( playerMesh );
mixer = new THREE.AnimationMixer( player );
mixers.set( player, mixer );
scene.add( player );