UNPKG

@motion-core/motion-gpu

Version:

Framework-agnostic WebGPU runtime for fullscreen WGSL shaders with explicit Svelte, React, and Vue adapter entrypoints.

81 lines (72 loc) 2.16 kB
import type { RenderPass, RenderPassContext, RenderPassFlags, RenderPassInputSlot, RenderPassOutputSlot } from '../core/types.js'; import { BlitPass } from './BlitPass.js'; export interface CopyPassOptions extends RenderPassFlags { enabled?: boolean; needsSwap?: boolean; input?: RenderPassInputSlot; output?: RenderPassOutputSlot; filter?: GPUFilterMode; } /** * Texture copy pass with fullscreen-blit fallback. */ export class CopyPass implements RenderPass { enabled: boolean; needsSwap: boolean; input: RenderPassInputSlot; output: RenderPassOutputSlot; clear: boolean; clearColor: [number, number, number, number]; preserve: boolean; private readonly fallbackBlit: BlitPass; constructor(options: CopyPassOptions = {}) { this.enabled = options.enabled ?? true; this.needsSwap = options.needsSwap ?? true; this.input = options.input ?? 'source'; this.output = options.output ?? (this.needsSwap ? 'target' : 'source'); this.clear = options.clear ?? false; this.clearColor = options.clearColor ?? [0, 0, 0, 1]; this.preserve = options.preserve ?? true; this.fallbackBlit = new BlitPass({ enabled: true, needsSwap: false, input: this.input, output: this.output, ...(options.filter !== undefined ? { filter: options.filter } : {}) }); } setSize(width: number, height: number): void { this.fallbackBlit.setSize(width, height); } render(context: RenderPassContext): void { const source = context.input; const target = context.output; const canDirectCopy = context.clear === false && context.preserve === true && source.texture !== target.texture && source.texture !== context.canvas.texture && target.texture !== context.canvas.texture && source.width === target.width && source.height === target.height && source.format === target.format; if (canDirectCopy) { context.commandEncoder.copyTextureToTexture( { texture: source.texture }, { texture: target.texture }, { width: source.width, height: source.height, depthOrArrayLayers: 1 } ); return; } this.fallbackBlit.render(context); } dispose(): void { this.fallbackBlit.dispose(); } }