Minimal instancedMesh example #761
-
I'm learning the basics of instancing meshes, but my minimal example isn't working as expected. // This displays a box
function Thing() {
return (
<mesh>
<boxBufferGeometry args={[1, 1, 1]} />
<meshNormalMaterial />
</mesh>
)
}
// This doesn't display anything
function InstancedThing() {
return (
<instancedMesh args={[null, null, 1]}>
<boxBufferGeometry args={[1, 1, 1]} />
<meshNormalMaterial />
</instancedMesh>
)
} "json" on Discord noted that they've had the same trouble recently and could only get around it by imperatively creating the geometry and material, but it's unclear to my why the declarative approach doesn't work. Am I doing something wrong or is this a problem with r3f? Edit: even when creating the geometry and material imperatively it doesn't work. Here's a sandbox that shows all three approaches, uncomment to see each component's result |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
Answering my own question for future readers: A function InstancedThing() {
const ref = useRef()
useEffect(() => {
ref.current.setMatrixAt(0, new THREE.Matrix4())
}, [])
return (
<instancedMesh ref={ref} args={[null, null, 1]}>
<boxBufferGeometry args={[1, 1, 1]} />
<meshNormalMaterial />
</instancedMesh>
)
} Note that the Three.js docs say you need to flag |
Beta Was this translation helpful? Give feedback.
Answering my own question for future readers:
A
THREE.InstancedMesh
stores all the 4x4 transformation matrices of all the instances inside a one flatFloat32Array
, which gets initialized to all zeros. A transformation matrix full of zeros means that the instances get squashed into the abyss, hence nothing gets rendered. To solve this you need to give the instances a more reasonable tranformation matrix, like an identity matrix. ATHREE.Matrix4()
will initialize to an identity matrix by default, so a minimal working version of the above example looks like: