API Reference

FragCanvas Reference

Complete prop reference and usage guide for the main FragCanvas component.


This is the complete prop reference for FragCanvas — the main adapter entrypoint for using Motion GPU in Svelte, React, and Vue.

Import

import { FragCanvas } from '@motion-core/motion-gpu/svelte';
import { FragCanvas } from '@motion-core/motion-gpu/svelte';

Usage

<FragCanvas
  material={myMaterial}
  clearColor={[0, 0, 0, 1]}
  color={{ outputEncoding: 'srgb', toneMapping: 'khronos-pbr-neutral' }}
  renderMode="always"
  passes={[vignettePass]}
  onError={handleError}
>
  <Runtime />
</FragCanvas>
<FragCanvas
  material={myMaterial}
  clearColor={[0, 0, 0, 1]}
  color={{ outputEncoding: 'srgb', toneMapping: 'khronos-pbr-neutral' }}
  renderMode="always"
  passes={[vignettePass]}
  onError={handleError}
>
  <Runtime />
</FragCanvas>

Adapter-specific naming differences (class vs className vs canvasClass, style type, children/slots) are listed below.

Props

Required

Prop Type Description
material FragMaterial The material to render. Must be created with defineMaterial().

Rendering

Prop Type Default Description
clearColor [number, number, number, number] [0, 0, 0, 1] RGBA clear color applied before the base pass.
color ColorPipelineOptions undefined Output encoding, HDR working format, canvas dynamic range, canvas color space, and final tone-mapping options. Changing triggers renderer rebuild.
renderMode 'always' | 'on-demand' | 'manual' 'always' Controls frame rendering frequency.
autoRender boolean true Hard gate — when false, no rendering occurs regardless of render mode.
maxDelta number 0.1 Maximum frame delta in seconds (clamps state.delta). Must be > 0.
dpr number devicePixelRatio (or 1 during SSR) Device pixel ratio for resolution scaling.

Color pipeline

color controls the private final presentation stage. It is not a composable render pass; it always runs after the base scene and after all post-scene render passes.

type ColorPipelineOptions = {
  outputEncoding?: 'srgb' | 'linear';
  toneMapping?: 'none' | 'khronos-pbr-neutral';
  dynamicRange?: 'sdr' | 'hdr' | 'auto';
  canvasColorSpace?: 'srgb' | 'display-p3';
  workingFormat?: 'auto' | GPUTextureFormat;
};
type ColorPipelineOptions = {
  outputEncoding?: 'srgb' | 'linear';
  toneMapping?: 'none' | 'khronos-pbr-neutral';
  dynamicRange?: 'sdr' | 'hdr' | 'auto';
  canvasColorSpace?: 'srgb' | 'display-p3';
  workingFormat?: 'auto' | GPUTextureFormat;
};
Option Default Description
outputEncoding 'srgb' Final value encoding. 'srgb' applies linear-to-sRGB encoding before SDR presentation; 'linear' leaves values unchanged.
toneMapping 'none' 'khronos-pbr-neutral' applies Khronos PBR Neutral to linear HDR input before SDR presentation.
dynamicRange 'sdr' 'hdr' requests rgba16float canvas output with WebGPU toneMapping: { mode: 'extended' }; 'auto' tries HDR and falls back to SDR.
canvasColorSpace 'srgb' Canvas presentation color space passed to WebGPU context configuration. This selects the canvas gamut/presentation space; it is separate from outputEncoding.
workingFormat 'auto' Internal scene/pass target format. auto selects rgba16float for HDR or tone-mapped pipelines, otherwise the preferred canvas format.

Khronos PBR Neutral is an SDR tone mapper: it consumes non-negative linear Rec.709 HDR color and returns linear Rec.709 in [0, 1]. Explicit dynamicRange: 'hdr' with toneMapping: 'khronos-pbr-neutral' is rejected because that combination asks for HDR presentation after an SDR tone mapper.

<FragCanvas
  {material}
  color={{ toneMapping: 'khronos-pbr-neutral' }}
/>
<FragCanvas
  {material}
  color={{ toneMapping: 'khronos-pbr-neutral' }}
/>
<FragCanvas
  material={material}
  color={{ dynamicRange: 'hdr', canvasColorSpace: 'display-p3' }}
/>
<FragCanvas
  material={material}
  color={{ dynamicRange: 'hdr', canvasColorSpace: 'display-p3' }}
/>

Post-processing

Prop Type Default Description
passes AnyPass[] [] Array of compute and render passes. Compute passes dispatch pre-scene in declaration order; render passes execute post-scene in declaration order. See Render Passes and Compute Shaders.
renderTargets RenderTargetDefinitionMap {} Named off-screen render targets. See Render Targets.

WebGPU configuration

Prop Type Default Description
adapterOptions GPURequestAdapterOptions undefined Forwarded to navigator.gpu.requestAdapter(). Can specify powerPreference, forceFallbackAdapter, etc.
deviceDescriptor GPUDeviceDescriptor undefined Forwarded to adapter.requestDevice(). Can request specific features or limits.

Error handling

Prop Type Default Description
showErrorOverlay boolean true Enables error UI rendering (errorRenderer or default overlay).
errorRenderer Snippet<[MotionGPUErrorReport]> (Svelte) / (report: MotionGPUErrorReport) => ReactNode (React) / scoped slot #errorRenderer="{ report }" (Vue) undefined Custom error renderer. When set, replaces the default MotionGPUErrorOverlay.
onError (report: MotionGPUErrorReport) => void undefined Error callback. Called regardless of overlay state. See Error Handling for report shape.
errorHistoryLimit number 0 Enables bounded error history when > 0; values are normalized with Math.floor.
onErrorHistory (history: MotionGPUErrorReport[]) => void undefined Callback with deduplicated ring-buffer history snapshots.

Error history behavior

  • History is disabled when errorHistoryLimit <= 0.
  • History stores the latest N reports when errorHistoryLimit > 0.
  • Consecutive identical reports are deduplicated (phase/title/message/rawMessage key).
  • Reducing errorHistoryLimit trims existing history immediately.

Styling and children

Prop Type Default Description
class (Svelte) / className (React) / canvasClass (Vue) string '' CSS class applied directly to the <canvas>.
style (Svelte/React) / canvasStyle (Vue) string (Svelte) / React.CSSProperties (React) / string Record<string, string number> (Vue) '' (Svelte) / undefined (React/Vue) Inline styles applied directly to the <canvas>.
children (Svelte/React) / default slot (Vue) Snippet (Svelte) / ReactNode (React) / slot (Vue) undefined Children rendered inside the FragCanvas context — this is where useFrame, useMotionGPU, usePointer, etc. work.

Lifecycle

Phase What happens
Mount Frame registry and context created. Material resolved. Pipeline signature computed. Renderer created (async). RAF loop started.
Frame Timing computed. Size updated. Scheduler tasks run. Render gate evaluated. If open: uniforms merged, textures uploaded, passes executed, frame presented.
Signature change Old renderer destroyed. New renderer created with updated signature. Exponential backoff on failure.
Destroy RAF cancelled. Renderer destroyed (GPU resources freed). Scheduler cleared.

Canvas sizing

FragCanvas renders a <canvas> inside a container <div>. The canvas fills its container using width: 100%; height: 100% CSS. The container determines the effective canvas dimensions.

The physical size (GPU resolution) is containerSize × dpr.

Example: full configuration

<FragCanvas
  material={material}
  clearColor={[0.05, 0.05, 0.1, 1]}
  color={{ outputEncoding: 'srgb', toneMapping: 'khronos-pbr-neutral' }}
  renderMode="on-demand"
  autoRender={true}
  maxDelta={0.05}
  dpr={2}
  passes={[tonePass, vignettePass]}
  renderTargets={{ halfRes: { scale: 0.5 } }}
  adapterOptions={{ powerPreference: 'high-performance' }}
  showErrorOverlay={true}
  errorRenderer={myErrorRenderer}
  onError={(report) => sendToTelemetry(report)}
  errorHistoryLimit={20}
  onErrorHistory={(history) => sendErrorHistory(history)}
  class="my-canvas-container"
  style="border-radius: 12px; overflow: hidden;"
>
  <Runtime />
</FragCanvas>
<FragCanvas
  material={material}
  clearColor={[0.05, 0.05, 0.1, 1]}
  color={{ outputEncoding: 'srgb', toneMapping: 'khronos-pbr-neutral' }}
  renderMode="on-demand"
  autoRender={true}
  maxDelta={0.05}
  dpr={2}
  passes={[tonePass, vignettePass]}
  renderTargets={{ halfRes: { scale: 0.5 } }}
  adapterOptions={{ powerPreference: 'high-performance' }}
  showErrorOverlay={true}
  errorRenderer={myErrorRenderer}
  onError={(report) => sendToTelemetry(report)}
  errorHistoryLimit={20}
  onErrorHistory={(history) => sendErrorHistory(history)}
  class="my-canvas-container"
  style="border-radius: 12px; overflow: hidden;"
>
  <Runtime />
</FragCanvas>
{#snippet myErrorRenderer(report)}
  <aside class="my-error-banner">
    <strong>{report.title}</strong>
    <p>{report.message}</p>
  </aside>
{/snippet}
{#snippet myErrorRenderer(report)}
  <aside class="my-error-banner">
    <strong>{report.title}</strong>
    <p>{report.message}</p>
  </aside>
{/snippet}