@motion-core/motion-gpu
Version:
Framework-agnostic WebGPU runtime for fullscreen WGSL shaders with explicit Svelte, React, and Vue adapter entrypoints.
75 lines (69 loc) • 2.05 kB
JavaScript
import { FullscreenPass } from "./FullscreenPass.js";
//#region src/lib/passes/ShaderPass.ts
var SHADER_PASS_CONTRACT = /\bfn\s+shade\s*\(\s*inputColor\s*:\s*vec4f\s*,\s*uv\s*:\s*vec2f\s*\)\s*->\s*vec4f/;
function buildShaderPassProgram(fragment) {
if (!SHADER_PASS_CONTRACT.test(fragment)) throw new Error("ShaderPass fragment must declare `fn shade(inputColor: vec4f, uv: vec2f) -> vec4f`.");
return `
struct MotionGPUVertexOut {
position: vec4f,
uv: vec2f,
};
var motiongpuShaderPassSampler: sampler;
var motiongpuShaderPassTexture: texture_2d<f32>;
fn motiongpuShaderPassVertex( index: u32) -> MotionGPUVertexOut {
var positions = array<vec2f, 3>(
vec2f(-1.0, -3.0),
vec2f(-1.0, 1.0),
vec2f(3.0, 1.0)
);
let position = positions[index];
var out: MotionGPUVertexOut;
out.position = vec4f(position, 0.0, 1.0);
out.uv = (position + vec2f(1.0, 1.0)) * 0.5;
return out;
}
${fragment}
fn motiongpuShaderPassFragment(in: MotionGPUVertexOut) -> vec4f {
let inputColor = textureSample(motiongpuShaderPassTexture, motiongpuShaderPassSampler, in.uv);
return shade(inputColor, in.uv);
}
`;
}
/**
* Fullscreen programmable shader pass.
*/
var ShaderPass = class extends FullscreenPass {
fragment;
program;
constructor(options) {
super(options);
this.fragment = options.fragment;
this.program = buildShaderPassProgram(options.fragment);
}
/**
* Replaces current shader fragment and invalidates pipeline cache.
*/
setFragment(fragment) {
const nextProgram = buildShaderPassProgram(fragment);
this.fragment = fragment;
this.program = nextProgram;
this.invalidateFullscreenCache();
}
getFragment() {
return this.fragment;
}
getProgram() {
return this.program;
}
getVertexEntryPoint() {
return "motiongpuShaderPassVertex";
}
getFragmentEntryPoint() {
return "motiongpuShaderPassFragment";
}
};
//#endregion
export { ShaderPass };
//# sourceMappingURL=ShaderPass.js.map