Visit the Documentation of the upcoming Threlte 6.
  1. @threlte/core
  2. InstancedMesh



This module will be moved to @threlte/extras at some point in the future. Please read the update notice.

The <InstancedMesh> is a special version of <Mesh> with instanced rendering support. Use <InstancedMesh> if you have to render a large number of objects with the same geometry and material but with different world transformations and colors. The usage of <InstancedMesh> will help you to reduce the number of draw calls and thus improve the overall rendering performance in your application.



Github View Source Code


NPM View Package

Related Docs


An <InstancedMesh> is used in conjunction with the <Instance> component:

<InstancedMesh {geometry} {material}>
  <Instance />
  <Instance />

It's also possible to nest other objects in an <InstancedMesh> component:

<InstancedMesh {geometry} {material}>
  <Instance />
  <Instance />

  <GLTF />

Provide an id to use multiple <InstancedMesh> components:

<InstancedMesh id="tree" geometry={treeGeometry} material={treeMaterial}>
  <InstancedMesh id="leaf" geometry={leafGeometry} material={leafMaterial}>
    <Group position={{ x: 1 }}>
      <Instance id="tree" /> // Instance of InstancedMesh with id="tree"
      <Instance id="leaf" /> // Instance of InstancedMesh with id="leaf"

    <Group position={{ x: -2 }}>
      <Instance id="tree" />
      <Instance id="leaf" />

Instance count

Usually you don't have to worry to set the property count of the underlying THREE.InstancedMesh as the component <InstancedMesh> automatically scales with the nested <Instance> components. In some occasions (e.g. when the amount of instances changes frequently) it might be beneficial to explicitly set the maximum amount of instances:

<InstancedMesh count={10} {geometry} {material}>
  <Instance />
  <Instance />


Instances also supports DOM-like events like the <Mesh> component, the setup however is a bit different. Although you can listen to events on <Instance> components, interactive and ignorePointer need to be set on the <InstancedMesh> component:

<InstancedMesh interactive {geometry} {material}>
  <Instance on:click={onClick} />

This means you can't exclude one instance from raycasting while listening for events on another.


Instances can be nested in other objects and all parent transformations apply as usual:

<InstancedMesh interactive {geometry} {material}>
  <Group rotation={{ z: DEG2RAD * 180 }}>
    <Instance />

    <Group position={{ y: 2 }}>
      <Instance />

Nesting instances might have a slight performance hit, the frameloop will run continuously. Use with caution.



// required
geometry: THREE.BufferGeometry
material: THREE.Material | THREE.Material[]

// optional
count: number | undefined = undefined
id: string = ''
position: Position | undefined = undefined
scale: Scale | undefined = undefined
rotation: Rotation | undefined = undefined
lookAt: LookAt | undefined = undefined
viewportAware: boolean = false
castShadow: boolean | undefined = undefined
receiveShadow: boolean | undefined = undefined
renderOrder: number | undefined = undefined
visible: boolean | undefined = undefined
dispose: boolean | undefined = undefined
userData: Record<string, any> | undefined = undefined
interactive: boolean = false
ignorePointer: boolean = false


instancedMesh: Writable<InstancedMesh>
inViewport: boolean


viewportenter: undefined
viewportleave: undefined