API Reference

Passes API

Reference for ShaderPass, BlitPass, CopyPass, ComputePass, PingPongComputePass, PingPongShaderPass, and pass slot contracts.


Reference for post-processing, fragment-feedback, and compute APIs shared by Svelte/React/Vue adapters and core entrypoints.

Entrypoints

Entrypoint Exports
@motion-core/motion-gpu/svelte ShaderPass, BlitPass, CopyPass, ComputePass, PingPongComputePass, PingPongShaderPass
@motion-core/motion-gpu/react ShaderPass, BlitPass, CopyPass, ComputePass, PingPongComputePass, PingPongShaderPass
@motion-core/motion-gpu/vue ShaderPass, BlitPass, CopyPass, ComputePass, PingPongComputePass, PingPongShaderPass
@motion-core/motion-gpu ShaderPass, BlitPass, CopyPass, ComputePass, PingPongComputePass, PingPongShaderPass

Shared render-pass options

ShaderPass, BlitPass, and CopyPass share these post-scene render-pass options:

Option Default Description
enabled true Whether pass participates in current frame plan
needsSwap true Swap source/target after execution
input 'source' Input slot (source, target, named target)
output 'target' (if swap) Output slot (source, target, canvas, named target)
clear false Clear output before drawing
clearColor [0, 0, 0, 1] RGBA clear color
preserve true Preserve output after pass

ShaderPass

Programmable post-process pass.

Required shader contract:

fn shade(inputColor: vec4f, uv: vec2f) -> vec4f
fn shade(inputColor: vec4f, uv: vec2f) -> vec4f

Additional option:

Option Type Description
fragment string Required WGSL shader source
filter GPUFilterMode Texture sampling mode

Runtime update API:

setFragment(nextFragment: string): void
setFragment(nextFragment: string): void

BlitPass

Fullscreen texture sample pass with configurable filter ('linear' or 'nearest').

CopyPass

Attempts direct GPU texture copy (copyTextureToTexture) and falls back to blit if conditions are not met.

Direct-copy path requires all of:

  • clear === false
  • preserve === true
  • source and output are different textures
  • neither surface is canvas
  • matching dimensions and format

ComputePass

GPU compute pass for single-dispatch workloads.

Compute passes are renderer-managed pre-scene workloads. The public extension point is the WGSL source plus dispatch strategy passed to ComputePass or PingPongComputePass.

Required shader contract:

@compute @workgroup_size(X, Y?, Z?)
fn compute(@builtin(global_invocation_id) id: vec3u)
@compute @workgroup_size(X, Y?, Z?)
fn compute(@builtin(global_invocation_id) id: vec3u)

All three elements are validated at construction time: the @compute annotation, @workgroup_size(...), and @builtin(global_invocation_id) parameter.

Options

Option Type Default Description
compute string Required WGSL compute shader source
dispatch [number, number?, number?] 'auto' (ctx) => [number, number, number] 'auto' Workgroup dispatch strategy
enabled boolean true Whether pass is active

Runtime update API

setCompute(source: string): void
setDispatch(dispatch: ComputePassOptions['dispatch']): void
getCompute(): string
getWorkgroupSize(): [number, number, number]
resolveDispatch(ctx: ComputeDispatchContext): [number, number, number]
setCompute(source: string): void
setDispatch(dispatch: ComputePassOptions['dispatch']): void
getCompute(): string
getWorkgroupSize(): [number, number, number]
resolveDispatch(ctx: ComputeDispatchContext): [number, number, number]

ComputeDispatchContext

Field Type
width number
height number
time number
delta number
workgroupSize [number, number, number]

PingPongComputePass

Iterative compute pass for multi-step GPU simulations.

Options

Option Type Default Description
compute string Required WGSL compute shader source
target string Required Storage texture key from material.textures (storage: true). Storage texture targets require explicit width and height.
iterations number 1 Iterations per frame (must be >= 1)
dispatch dispatch mode 'auto' Workgroup dispatch strategy
enabled boolean true Whether pass is active

Runtime update API

getCurrentOutput(): string          // Texture key holding latest result ({target}A or {target}B)
advanceFrame(): void                // Advance internal counter (called by renderer)
setIterations(count: number): void
setCompute(source: string): void
setDispatch(dispatch): void
getTarget(): string
getIterations(): number
getCompute(): string
getWorkgroupSize(): [number, number, number]
resolveDispatch(ctx: ComputeDispatchContext): [number, number, number]
getCurrentOutput(): string          // Texture key holding latest result ({target}A or {target}B)
advanceFrame(): void                // Advance internal counter (called by renderer)
setIterations(count: number): void
setCompute(source: string): void
setDispatch(dispatch): void
getTarget(): string
getIterations(): number
getCompute(): string
getWorkgroupSize(): [number, number, number]
resolveDispatch(ctx: ComputeDispatchContext): [number, number, number]

Properties

Property Type Description
isCompute true Discriminant for pre-scene compute planning
isPingPong true Ping-pong identifier
enabled boolean Active state

PingPongShaderPass

Iterative fragment-feedback pass for fullscreen simulations that read the previous texture state and write the next one. The renderer executes it in the pre-scene phase, owns two A/B render textures, and exposes the latest output through the declared material texture target before the base scene renders.

Required shader contract:

fn frag(uv: vec2f) -> vec4f
fn frag(uv: vec2f) -> vec4f

The generated shader adds these previous-state bindings:

@group(1) @binding(0) var motiongpuPreviousSampler: sampler;
@group(1) @binding(1) var motiongpuPrevious: texture_2d<f32>;
@group(1) @binding(0) var motiongpuPreviousSampler: sampler;
@group(1) @binding(1) var motiongpuPrevious: texture_2d<f32>;

group(0) contains frame uniforms, user uniforms, and fragment-visible material textures except the target texture. The target is intentionally excluded while the feedback pass is writing, so read previous state only through motiongpuPrevious.

Options

Option Type Default Description
fragment string Required WGSL fragment source containing fn frag(uv: vec2f) -> vec4f
target string Required Material texture key that receives the latest feedback output. Must be fragment-visible and must not be storage: true.
width number canvas width × scale Explicit feedback texture width
height number canvas height × scale Explicit feedback texture height
scale number 1 Canvas-relative scale for implicit dimensions
format GPUTextureFormat 'rgba16float' A float-sampled render texture format
filter GPUFilterMode 'linear' Previous-state sampler filter
addressModeU GPUAddressMode 'clamp-to-edge' Previous-state sampler U address mode
addressModeV GPUAddressMode 'clamp-to-edge' Previous-state sampler V address mode
iterations number 1 Fragment iterations per frame (must be >= 1)
clearColor [number, number, number, number] [0, 0, 0, 0] Color used to initialize or reset both A/B textures
defines MaterialDefines {} Compile-time constants injected before the fragment
includes MaterialIncludes {} WGSL chunks used by #include <name> directives
enabled boolean true Whether pass is active

Runtime update API

setFragment(fragment: string, options?: { defines?: MaterialDefines; includes?: MaterialIncludes }): void
setIterations(count: number): void
setDimensions(width?: number, height?: number): void
setScale(scale: number): void
reset(clearColor?: [number, number, number, number]): void
consumeResetColor(): [number, number, number, number] | null
getCurrentOutput(): string          // Texture key holding latest result ({target}A or {target}B)
advanceFrame(): void                // Advance internal counter (called by renderer)
resolveSize(canvasSize: { width: number; height: number }): { width: number; height: number }
getTarget(): string
getFragment(): string
getFragmentLineMap(): MaterialLineMap
getIterations(): number
getFormat(): GPUTextureFormat
getFilter(): GPUFilterMode
getAddressModeU(): GPUAddressMode
getAddressModeV(): GPUAddressMode
getClearColor(): [number, number, number, number]
setFragment(fragment: string, options?: { defines?: MaterialDefines; includes?: MaterialIncludes }): void
setIterations(count: number): void
setDimensions(width?: number, height?: number): void
setScale(scale: number): void
reset(clearColor?: [number, number, number, number]): void
consumeResetColor(): [number, number, number, number] | null
getCurrentOutput(): string          // Texture key holding latest result ({target}A or {target}B)
advanceFrame(): void                // Advance internal counter (called by renderer)
resolveSize(canvasSize: { width: number; height: number }): { width: number; height: number }
getTarget(): string
getFragment(): string
getFragmentLineMap(): MaterialLineMap
getIterations(): number
getFormat(): GPUTextureFormat
getFilter(): GPUFilterMode
getAddressModeU(): GPUAddressMode
getAddressModeV(): GPUAddressMode
getClearColor(): [number, number, number, number]

Properties

Property Type Description
isPingPongShader true Discriminant for pre-scene fragment-feedback planning
enabled boolean Active state

Texture coordinates

PingPongShaderPass uv is aligned with the feedback render texture so previous-state reads and current writes hit the same row across iterations. When the target is sampled later by a normal material using its public Y-up frag(uv) coordinates, the visible result lines up with the material shader.

Slot constraints

Rule Effect
needsSwap: true must be input: 'source' + output: 'target' Invalid combinations throw
canvas is output-only input: 'canvas' throws
Named targets must exist in renderTargets Unknown target names throw
Named targets must be written before read in frame plan Read-before-write throws

Compute and fragment-feedback passes do not participate in slot routing. They have no input, output, or needsSwap options, and they always execute before the base scene render. Render pass order is preserved only within the post-scene render-pass group.