Multiple Instances of Skinned Mesh won't show (React Three Fiber)

Hi,

So strange situation, I’m trying to render several ‘worm like’ creatures on a page, however they’re skinned meshes. I’m mapping over a list of positions to display them, however only the first one ever renders,

As you can see from this image, both the green boxGeometries show fine, but only the first skinned mesh shows, I’ve created a codesandbox here https://codesandbox.io/s/skinned-mesh-problem-o9kitl to show the problem. Anyone know why the additional skinned meshes aren’t showing?

My Scene.js is

import { OrbitControls, PerspectiveCamera } from "@react-three/drei";
import React, { useMemo } from "react";
import { Tube2 } from "./Tube2";

const Scene = () => {
  const tubes = useMemo(() => {
    return [
      [5, 2, 5],
      [0, 2, 0]
    ];
  });

  return (
    <>
      <ambientLight intensity={0.3} />
      <pointLight position={[5, 5, 0]} />
      <OrbitControls />
      <PerspectiveCamera makeDefault position={[15, 15, 15]} />
      {tubes.map((pos, i) => {
        return <Tube2 key={JSON.stringify(pos)} position={pos} />;
      })}
    </>
  );
};

export default Scene;

And the Tube2.js is as follows:

import React, { useEffect, useRef } from "react";
import { useGLTF } from "@react-three/drei";
import { useFrame } from "@react-three/fiber";

export function Tube2(props) {
  const { nodes, materials } = useGLTF("/tube2-transformed.glb");
  return (
    <group {...props} dispose={null}>
      <primitive object={nodes.Bone} />
      <skinnedMesh
        material-color={props.col}
        geometry={nodes.Sphere.geometry}
        material={nodes.Sphere.material}
        skeleton={nodes.Sphere.skeleton}
      />
      <mesh>
        <boxGeometry args={[2, 2, 2]} />
        <meshStandardMaterial color={"green"} />
      </mesh>
    </group>
  );
}

useGLTF.preload("/tube2-transformed.glb");

limitation in threejs, you can’t have one skinned mesh in two places, cloning also doesn’t work ootb. the solution is skeletonutils:

if you don’t need to lay out the model declaratively then drei/Clone will also do it as of late

import { Clone } from '@react-three/drei'

const { scene } = useGLTF(url)
...
return <Clone object={scene} {...props} />
2 Likes

btw do you even need skinning? i don’t see any animation being played. if you don’t then the cleanest solution would be to remove armatures, bones and keyframes in blender and re-export. a regular gltfjsx model can be re-used ootb.

Worked a treat, thank you!