<BakeShadows>
<BakeShadows> instantly freezes all shadow maps upon mounting and unfreezes them upon unmounting. This improves performance by making all shadows static. Use <BakeShadows if you have a complex but static scene as the shadows will only be calculated once.
<script lang="ts"> import Scene from './Scene.svelte' import { Canvas } from '@threlte/core' import { Checkbox, Pane } from 'svelte-tweakpane-ui'
let bake = $state(false)</script>
<Pane title="BakeShadows" position="fixed"> <Checkbox bind:value={bake} label="bake shadows" /></Pane>
<div> <Canvas> <Scene {bake} /> </Canvas></div>
<style> div { height: 100%; }</style><script lang="ts"> import { Mesh } from 'three' import { BakeShadows } from '@threlte/extras' import { T, useTask } from '@threlte/core'
type Props = { bake: boolean }
let { bake }: Props = $props()
const mesh = new Mesh()
useTask((delta) => { mesh.rotation.y += delta })</script>
<T.PerspectiveCamera makeDefault position={[10, 10, 10]} oncreate={(ref) => { ref.lookAt(0, 1, 0) }}/>
<T.DirectionalLight position={[0, 10, 10]} castShadow/>
<T is={mesh} castShadow position.y={1}> <T.BoxGeometry args={[1, 2, 1]} /> <T.MeshStandardMaterial color="orangered" /></T>
<T.Mesh receiveShadow rotation.x={-1 * 0.5 * Math.PI}> <T.CircleGeometry args={[4, 40]} /> <T.MeshStandardMaterial color="white" /></T.Mesh>
{#if bake} <BakeShadows />{/if}When <BakeShadows> is used within a <Suspense>, shadows will be frozen after the boundary is no longer in a suspended state. It will unfreeze if the boundary is re-suspended.
<script lang="ts"> import Scene from './Scene.svelte' import { Canvas } from '@threlte/core'</script>
<div> <Canvas> <Scene /> </Canvas></div>
<style> div { height: 100%; }</style><script lang="ts"> import Spaceship from './Spaceship.svelte' import type { SpaceshipProps } from './types' import { BakeShadows, OrbitControls, Suspense } from '@threlte/extras' import { Color } from 'three' import { T, useThrelte } from '@threlte/core'
const { size, scene } = useThrelte() scene.background = new Color('black')
let zoom = $derived($size.width / 50)
type Ship = Required<Pick<SpaceshipProps, 'name' | 'position'>>
const ships: Ship[] = [ { name: 'Bob', position: [-12, 0, 3] }, { name: 'Challenger', position: [10, 5, 6] }, { name: 'Dispatcher', position: [8, 3, -23] }, { name: 'Executioner', position: [12, -4, 6] }, { name: 'Imperial', position: [-1, 0, -21] }, { name: 'Insurgent', position: [-13, 1, -21] }, { name: 'Omen', position: [-9, -5, 13] }, { name: 'Pancake', position: [-9, -3, -9] }, { name: 'Spitfire', position: [1, 0, 1] }, { name: 'Striker', position: [8, -1, -10] }, { name: 'Zenith', position: [-1, 0, 13] } ]</script>
<T.OrthographicCamera position={[-40, 25, 40]} makeDefault {zoom} oncreate={(ref) => { ref.lookAt(0, 0, -8) }}> <OrbitControls /></T.OrthographicCamera>
<T.SpotLight position={[0, 25, 0]} castShadow intensity={1000} angle={Math.PI / 3}/>
<Suspense final> {#each ships as { name, position }} <Spaceship {name} {position} /> {/each} <BakeShadows /></Suspense>
<T.Mesh receiveShadow position.y={-10} rotation.x={-1 * 0.5 * Math.PI}> <T.CircleGeometry args={[100]} /> <T.MeshStandardMaterial color="white" /></T.Mesh><script lang="ts"> import type { SpaceshipProps } from './types' import { T } from '@threlte/core' import { useGltf, useSuspense } from '@threlte/extras'
let { name, ...props }: SpaceshipProps = $props()
const suspend = useSuspense()
let gltf = $derived(suspend(useGltf(`/models/spaceships/${name}.gltf`)))</script>
{#await gltf then { scene }} <T.Group {...props}> <T is={scene} oncreate={(ref) => { for (const child of ref.children) { child.castShadow = true child.receiveShadow = true } }} /> </T.Group>{/await}export type { SpaceshipProps } from '../../suspense/types'The example above is an ideal scene for <BakeShadows> because all objects are stationary and the shadows will never change.