UNPKG

@motion-core/motion-gpu

Version:

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

86 lines (85 loc) 2.65 kB
//#region src/lib/core/render-graph.ts /** * Creates a copy of RGBA clear color. */ function cloneClearColor(color) { return [ color[0], color[1], color[2], color[3] ]; } /** * Builds validated render graph plan from runtime pass list. * * @param passes - Runtime passes. * @param defaultClearColor - Global clear color fallback. * @returns Resolved render graph plan. */ function planRenderGraph(passes, defaultClearColor, renderTargetSlots) { const steps = []; const computeSteps = []; const renderSteps = []; const declaredTargets = new Set(renderTargetSlots ?? []); const availableSlots = new Set(["source"]); let finalOutput = "canvas"; let enabledIndex = 0; for (const pass of passes ?? []) { if (pass.enabled === false) continue; if ("isCompute" in pass && pass.isCompute === true) { const step = { kind: "compute", pass, input: "source", output: "source", needsSwap: false, clear: false, clearColor: cloneClearColor(defaultClearColor), preserve: true }; steps.push(step); computeSteps.push(step); continue; } const rp = pass; const needsSwap = rp.needsSwap ?? true; const input = rp.input ?? "source"; const output = rp.output ?? (needsSwap ? "target" : "source"); if (input === "canvas") throw new Error(`Render pass #${enabledIndex} cannot read from "canvas".`); if (input !== "source" && input !== "target" && !declaredTargets.has(input)) throw new Error(`Render pass #${enabledIndex} reads unknown target "${input}".`); if (output !== "source" && output !== "target" && output !== "canvas" && !declaredTargets.has(output)) throw new Error(`Render pass #${enabledIndex} writes unknown target "${output}".`); if (needsSwap && (input !== "source" || output !== "target")) throw new Error(`Render pass #${enabledIndex} uses needsSwap=true but does not follow source->target flow.`); if (!availableSlots.has(input)) throw new Error(`Render pass #${enabledIndex} reads "${input}" before it is written.`); const step = { kind: "render", pass, input, output, needsSwap, clear: rp.clear ?? false, clearColor: cloneClearColor(rp.clearColor ?? defaultClearColor), preserve: rp.preserve ?? true }; steps.push(step); renderSteps.push(step); if (needsSwap) { availableSlots.add("target"); availableSlots.add("source"); finalOutput = "source"; } else { if (output !== "canvas") availableSlots.add(output); finalOutput = output; } enabledIndex += 1; } return { steps, computeSteps, renderSteps, finalOutput }; } //#endregion export { planRenderGraph }; //# sourceMappingURL=render-graph.js.map