<InstancedMeshes>
The component <InstancedMeshes> takes existing THREE.Mesh instances and creates a THREE.InstancedMesh per THREE.Mesh. This is especially useful if you want to instantiate a lot of meshes that have been loaded with hooks like useGltf.
It takes the same arguments as <InstancedMesh>.
<script lang="ts"> import { Canvas } from '@threlte/core' import Scene from './Scene.svelte'</script>
<div> <Canvas> <Scene /> </Canvas></div>
<style> div { height: 100%; }</style><script lang="ts"> import type { Snippet } from 'svelte' import { T, type Props } from '@threlte/core' import { type Group, MathUtils } from 'three' interface GroupProps extends Props<Group> { children?: Snippet }
let { children, ...rest }: GroupProps = $props()</script>
<T.Group {...rest}> <!-- Correct rotation --> <T.Group rotation.x={MathUtils.DEG2RAD * 90}> {@render children?.()} </T.Group></T.Group><script lang="ts"> import { T } from '@threlte/core' import { InstancedMeshes, OrbitControls, useGltf } from '@threlte/extras' import { DoubleSide, Mesh } from 'three' import { DEG2RAD } from 'three/src/math/MathUtils.js' import Flower from './Flower.svelte'
const gltf = useGltf<{ nodes: { Blossom: Mesh Stem: Mesh } materials: {} }>('/models/Flower.glb')
// make an array of random x-z coordinates in the range of -20 to 20 with 200 elements const items = Array.from({ length: 1000 }, () => ({ x: Math.random() * 5 - 2.5, z: Math.random() * 5 - 2.5, scale: Math.random() * 0.5 + 0.5, rotation: { x: Math.random() * 8, y: Math.random() * 360, z: Math.random() * 8 } }))</script>
{#if $gltf} <InstancedMeshes castShadow meshes={$gltf.nodes} > {#snippet children({ components: { Blossom, Stem } })} {#each items as item} <Flower position.x={item.x} position.z={item.z} scale={item.scale} rotation.y={(item.rotation.y * Math.PI) / 180} rotation.x={(item.rotation.x * Math.PI) / 180} rotation.z={(item.rotation.z * Math.PI) / 180} > <Blossom /> <Stem /> </Flower> {/each} {/snippet} </InstancedMeshes>{/if}
<T.DirectionalLight position.y={10} position.z={5} castShadow shadow.camera.left={-2.5} shadow.camera.right={2.5} shadow.camera.top={2.5} shadow.camera.bottom={-2.5} shadow.mapSize.width={1024} shadow.mapSize.height={1024}/>
<T.Mesh receiveShadow rotation.x={-90 * DEG2RAD}> <T.PlaneGeometry args={[5, 5]} /> <T.MeshStandardMaterial color="#288278" side={DoubleSide} /></T.Mesh>
<T.AmbientLight intensity={0.1} />
<T.PerspectiveCamera position={[3, 0.5, 3]} makeDefault fov={20}> <OrbitControls autoRotate enableZoom={false} enableDamping autoRotateSpeed={0.1} enablePan={false} /></T.PerspectiveCamera>Passing a map
Section titled “Passing a map”Load a gltf file with the useGltf hook and pass the result to the <InstancedMeshes> component. The slot prop components can be used to instantiate a mesh multiple times.
<script lang="ts"> import { useGltf, InstancedMeshes } from '@threlte/extras'
// Let's say the file contains a mesh named "Cube". // The hook `useGltf` will automatically provide a map with // all nodes of the gltf file at the key `nodes`. When // passing that map to the `<InstancedMeshes>` component, it will // automatically filter out all nodes that are not // `THREE.Mesh` instances. const gltf = useGltf('path/to/file.gltf')</script>
{#if $gltf} <!-- You can use object destructuring to access the component <Cube> --> <InstancedMeshes meshes={$gltf.nodes}> {#snippet children({ components: { Cube } })} <Cube position.y={2} position.x={-1}> {/snippet} </InstancedMeshes>{/if}When using <InstancedMeshes> with a large gltf file, be aware that <InstancedMeshes> will
create a new <InstancedMesh> for each <Mesh> in the gltf file.
This can lead to a lot of <InstancedMesh> components, which can have a negative
impact on performance. You might want to filter out the meshes you want to
instantiate beforehand.
Passing an array
Section titled “Passing an array”If you don’t want to use the useGltf hook, you can also pass an array of THREE.Mesh instances to the <InstancedMeshes> component.
<script lang="ts"> import { InstancedMeshes } from '@threlte/extras' import { Mesh, BoxGeometry, MeshStandardMaterial } from 'three'
const meshes = [ new Mesh(new BoxGeometry(), new MeshStandardMaterial()), // MeshA new Mesh(new SphereGeometry(), new MeshStandardMaterial()), // MeshB new Mesh(new PlaneGeometry(), new MeshStandardMaterial()) // MeshC ]</script>
<!-- You can use array destructuring to access the components <MeshA>, <MeshB> and <MeshC> --><InstancedMeshes meshes={meshes}> {#snippet children({ components: [MeshA, MeshB, MeshC] })} <MeshA position.y={2} position.x={-1}> <MeshB position.y={-2}> <MeshC position.y={0} position.x={1}> {/snippet}</InstancedMeshes>Component Signature
Section titled “Component Signature”
<InstancedMeshes> extends
<
T
.
InstancedMesh
>
and supports all its props, snippets, bindings and events.