@threlte/extras
useGltf
A Hook to load glTF files and use separate object nodes and materials of it.
Use the component <GLTF>
if you want to use a model in its entirety.
<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 { T, useThrelte } from '@threlte/core'
import { OrbitControls } from '@threlte/extras'
import { Color } from 'three'
import Tokyo from './Tokyo.svelte'
const { scene } = useThrelte()
scene.background = new Color(0xeae8e2)
let showTokyo = true
</script>
<svelte:window
on:keypress={() => {
showTokyo = !showTokyo
}}
/>
<T.PerspectiveCamera
makeDefault
position={[600, 200, 600]}
near={10}
far={10000}
>
<OrbitControls
autoRotate
autoRotateSpeed={0.2}
enableDamping
enableZoom={false}
target={[-60, -75, 0]}
/>
</T.PerspectiveCamera>
<T.AmbientLight />
<T.DirectionalLight position={[5, 10, 5]} />
{#if showTokyo}
<Tokyo />
{/if}
<script lang="ts">
import { GLTF, useGltfAnimations } from '@threlte/extras'
const { gltf, actions } = useGltfAnimations<'Take 001'>()
$: $actions['Take 001']?.play()
</script>
<GLTF
bind:gltf={$gltf}
url="/models/LittlestTokyo.glb"
useDraco="https://www.gstatic.com/draco/v1/decoders/"
/>
<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 { T, useTask } from '@threlte/core'
import { Environment, useGltf } from '@threlte/extras'
import type { Material, Object3D } from 'three'
let rotation = 0
useTask((delta) => {
const f = 1 / 60 / delta // ~1 at 60fps
rotation += 0.005 * f
})
const gltf = useGltf<{
nodes: {
'node_damagedHelmet_-6514': Object3D
}
materials: {
Material_MR: Material
}
}>('/models/helmet/DamagedHelmet.gltf')
</script>
<Environment
path="/hdr/"
files="shanghai_riverside_1k.hdr"
/>
<T.PerspectiveCamera
makeDefault
position.z={10}
fov={20}
/>
<T.DirectionalLight
position.y={10}
position.z={10}
/>
<T.Group rotation.y={rotation}>
{#await gltf}
<!-- Place loading placeholder here -->
{:then value}
<T is={value.nodes['node_damagedHelmet_-6514']} />
{/await}
</T.Group>
Model: Battle Damaged Sci-fi Helmet by theblueturtle_
Examples
Basic Example
gltf
is a store which gets populated as soon as the model loaded.
<script lang="ts">
import { T } from '@threlte/core'
import { useGltf } from '@threlte/extras'
import { MeshBasicMaterial } from 'three'
const gltf = useGltf('/path/to/model.glb')
</script>
<!-- Use an object node entirely -->
{#if $gltf}
<T is={$gltf.nodes['node-name']} />
{/if}
<!-- or only the geometry -->
{#if $gltf}
<T.Mesh
geometry={$gltf.nodes['node-name'].geometry}
material={new MeshBasicMaterial()}
/>
{/if}
DRACO decoding
Use a DRACO decoder for compressed glTF files, defaults to CDN loaded DRACO binaries.
import { useGltf } from '@threlte/extras'
const gltf = useGltf('/path/to/model.glb', {
useDraco: true
})
You can set a custom path to DRACO decoder binaries.
import { useGltf } from '@threlte/extras'
const gltf = useGltf('/path/to/model.glb', {
useDraco: '/custom/draco/decoders/path'
})
You can also provide your own instance of DRACOLoader
import { useGltf } from '@threlte/extras'
const myLoader = new DRACOLoader().setDecoderPath(path)
const gltf = useGltf('/path/to/model.glb', {
useDraco: myLoader
})
Meshopt decoding
Use a meshopt decoder for compressed glTF files, defaults to Three’s included decoder.
import { useGltf } from '@threlte/extras'
const gltf = useGltf('/path/to/model.glb', {
useMeshopt: true
})
Nodes and Materials
The hook provides a map of all objects and materials in the loaded glTF.
<script lang="ts">
import { useGltf } from '@threlte/extras'
const gltf = useGltf('/path/to/model.glb')
$: nodes: $gltf?.nodes
$: materials: $gltf?.materials
</script>
Provide types and you will gain autocompletion for these objects and materials.
<script lang="ts">
import { useGltf } from '@threlte/extras'
const gltf = useGltf<{
nodes: {
MeshA: THREE.Mesh
MeshB: THREE.Mesh
Object3DA: THREE.Object3D
}
materials: {
MaterialA: THREE.MeshStandardMaterial
MaterialB: THREE.MeshBasicMaterial
}
}>('/path/to/model.glb')
$: if ($gltf) {
const objectA = $gltf.nodes['MeshA'] // -> THREE.Mesh
const materialA = $gltf.materials['MaterialA'] // -> THREE.MeshStandardMaterial
}
</script>
How to get the types?
On the loading-assets page, Threlte provides the
@threlte/gltf
CLI tool that can be used to generate a reusable Svelte component for your gltf as
well as its types.
Types can be separated into a typescript file and imported like so if you feel the need.
export type SomeGltf = {
nodes: {
Suzanne: THREE.Mesh
}
materials: {}
}
<script lang="ts">
import { useGltf } from '@threlte/extras'
import type { SomeGltf } from './SomeGltf.ts'
useGltf<SomeGltf>('model.glb')
</script>