Animated Instanced Skinned Meshes (GLTF)

Hello, Is there any update on this topic? I’m curious if there have been any recent developments. Thank you.

4 Likes

Hi thee @Fyrestar amazing work, i’d too be very interested in seeing how to achieve that :+1:

I ended up making my own version, it’s a plug and play class that anyone can use, a bit naive on the LOD but it works for single skinnedMesh (which is recommended anyway)

const instance = new InstancedEntity({
    skinned_mesh: model.scene.getObjectByName('find ur mesh'),
    actions: { idle: <cliped action>, run: <cliped action> },
    mixer: animation mixer,
})

const entity = instance.add_entity('uuid')
entity.set_position()
entity.set_animation('idle')

instance.tick(delta)

Otherwise you also have an npm package by @luisherasme NPM Package · Issue #1 · luis-herasme/instanced-skinned-mesh · GitHub

btw the shader used in the PR is wrong, it will basically only allow instanced skinnedMesh and not originals anymore, here is the fix

ShaderChunk.skinning_pars_vertex = /* glsl */ `
        #ifdef USE_SKINNING

          uniform mat4 bindMatrix;
          uniform mat4 bindMatrixInverse;

          uniform highp sampler2D boneTexture;
          uniform int boneTextureSize;

          mat4 getBoneMatrix( const in float i ) {

          #ifdef USE_INSTANCING

              int j = 4 * int(i);
              vec4 v1 = texelFetch(boneTexture, ivec2( j, gl_InstanceID ), 0);
              vec4 v2 = texelFetch(boneTexture, ivec2( j + 1, gl_InstanceID ), 0);
              vec4 v3 = texelFetch(boneTexture, ivec2( j + 2, gl_InstanceID ), 0);
              vec4 v4 = texelFetch(boneTexture, ivec2( j + 3, gl_InstanceID ), 0);

          #else

            int size = textureSize( boneTexture, 0 ).x;
            int j = int( i ) * 4;
            int x = j % size;
            int y = j / size;
            vec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 );
            vec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 );
            vec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 );
            vec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 );

          #endif

            mat4 bone = mat4( v1, v2, v3, v4 );

            return bone;

          }

        #endif
      `

Thanks for sharing.
I would make a small demo of it, but I can’t see any licence info in the GitHub repo

Go ahead, my project is open source so that we all progress together

1 Like

“open source” doesn’t mean that I can copy it and use it any way I wish.

Licences matter. Add a MIT licence to your repo so the boundaries are clear.

No license means “all rights reserved” (you can see it, but you can’t use it). You can paste a license in LICENSE.md.

Here’s a template:

https://opensource.org/license/mit

Hey there! Any updates about your promising work?

1 Like

Very impressive, is there any new information from this job?

Hello,

I’ve created something similar and would like to share it with you.
I wrote a library called InstancedMesh2, which now also supports skinning, and so I prepared a demo about it (3k animated instances).
You can find the demo code here.

Optimizations in this demo:

  • frustum culling
  • generates geometry LODs with meshoptimizer (5 LODs here)
  • animate only instances within the camera frustum
  • set animation fps based on camera distance for each instance (0 to 60)
  • update less bones if the instance is far away

Partial texture update should be improved.

7 Likes