Run the compiled program
A vertex and a fragment entry, and a host that runs them as an engine does. The module's default export is its manifest; the host loads it with rt.load() on the program runtime, makes a render pipeline, and draws a full-screen triangle into a texture each frame, binding the uniform by name. Then it reads the texture back (Rules 11.10, 11.11).
Runs on WebGPUWebGL2
The compiler checks this list: a tier is on it exactly when the host's whole run gives the reference with that tier alone. Its journeys gate runs each host on WebGPU and on WebGL2, and its unit suite runs each one on the CPU tier.
"use typeshade";
/* @example{ "title": "Host: run the compiled program", "blurb": "A vertex and a fragment entry, and a host that runs them as an engine does. The module's default export is its manifest; the host loads it with `rt.load()` on the program runtime, makes a render pipeline, and draws a full-screen triangle into a texture each frame, binding the uniform by name. Then it reads the texture back (Rules 11.10, 11.11).", "renderable": true}*/
class Sky { size: vec2; time: f32;}
declare const sky: uniform<Sky>;
class VsOut { @builtin("position") pos: vec4;}
class Color { @location(0) color: vec4;}
// Three vertices that cover the target: the host draws `{ count: 3 }` and binds no vertex buffer.@vertexexport function vs(@builtin("vertex_index") vi: u32): VsOut { const x = f32(i32(vi) / 2) * 4. - 1.; const y = f32(i32(vi) % 2) * 4. - 1.; return { pos: vec4(x, y, 0., 1.) };}
@fragmentexport function fs(@builtin("position") p: vec4): Color { const uv = p.xy / sky.size; return { color: vec4(uv.x, 1. - uv.y, 0.5 + 0.5 * cos(sky.time), 1.) };}// Run a module's compiled program on the program runtime, as an engine does (surface §69, Rules// 11.10 and 11.11).//// A shader module's default export is its manifest: the WGSL, the GLSL ES 3.00 programs, and each// binding with its layout. `typeshade/runtime` loads it on WebGPU, or on WebGL2, and makes the// pipelines; the host records frames and binds values by name.import { runtime } from 'typeshade/runtime';import program from './host-program.shade.ts';
/** Draw a frame into a `width` by `height` texture at each of `times`, then read it back: * RGBA, one byte to a channel, the top row first. */export async function run( width = 32, height = 32, times: readonly number[] = [0, 0.5, 1.25],): Promise<Uint8Array> { const rt = await runtime(); // the default runtime: WebGPU, or WebGL2 const pipeline = await rt.load(program).render({ targets: ['rgba8unorm'] }); const target = rt.texture({ size: [width, height], format: 'rgba8unorm' }); for (const time of times) { const frame = rt.frame(); frame.pass({ color: [target] }, (pass) => pass.draw(pipeline, { sky: { size: [width, height], time } }, { count: 3 }), ); await frame.submit(); } const pixels = await target.read(); // the last frame target.destroy(); return pixels;}Both files are the compiler's own at commit 91c2fe31, from the examples directory.