useTexture is an adapter runtime hook that loads textures from URLs, exposes reactive loading and both raw/normalized error state, and handles cancellation and resource cleanup automatically.
For texture declaration and configuration in materials, see Texture Definitions.
Basic usage
<script lang="ts">
import { useFrame, useTexture } from '@motion-core/motion-gpu/svelte';
const loaded = useTexture(['/assets/albedo.png']);
useFrame((state) => {
const tex = loaded.textures.current?.[0];
state.setTexture('uAlbedo', tex ? { source: tex.source } : null);
});
</script>useTexture starts loading immediately when called. It returns reactive stores that update as the load progresses.
URL input forms
Return value (UseTextureResult)
Using .current for synchronous access
All stores expose a .current getter for zero-subscription reads — ideal for useFrame callbacks:
Using reactive subscriptions for UI
<script lang="ts">
const { textures, loading, error, errorReport } = useTexture(['/assets/albedo.png']);
</script>
{#if $loading}
<p>Loading textures...</p>
{:else if $error}
<p>Error: {$error.message}</p>
{#if $errorReport}
<p>Code: {$errorReport.code}</p>
<p>Hint: {$errorReport.hint}</p>
{/if}
{:else}
<p>Loaded {$textures?.length ?? 0} textures</p>
{/if}TextureLoadOptions
TextureDecodeOptions
Example with options
LoadedTexture shape
Each loaded texture provides:
Abort, reload, and race safety
useTexture is designed for safe async operation in a reactive environment:
Cancellation on reload
When reload() is called, any in-flight request is aborted before the new one starts. This prevents stale results from overwriting fresh data.
Request versioning
Each load increments an internal version counter. When a response arrives, it is only accepted if its version matches the current counter. This eliminates race conditions from overlapping loads.
Dispose on replacement
When new textures are loaded successfully, the previous bitmaps are disposed. When the component is destroyed, all current bitmaps are disposed.
Abort error suppression
AbortError exceptions are treated as expected cancellation and are not surfaced in the error or errorReport stores. Only genuine failures (network errors, decode errors, etc.) appear.
Blob cache
Under the hood, texture-loader.ts maintains a reference-counted blob cache. This means:
- If two
useTexturecalls request the same URL with the same options, only one network request is made. - The cache key is deterministic:
JSON.stringify({ url, colorSpace, requestInit, decode }). - Entries are evicted when their reference count drops to zero (e.g., all components using that URL are destroyed).
Component lifecycle
useTexture performs adapter lifecycle cleanup automatically:
- On destroy/unmount,
disposedflag is set. - The internal
requestVersionis incremented (invalidating any in-flight result). - The active
AbortControlleris aborted. - All current bitmap textures are disposed.
This means you don’t need to manually clean up — the hook handles its own lifecycle.