One helper on the CPU and the GPU

One helper on the CPU and the GPU

A terrain height function that the fragment entry draws on the GPU and the host calls on the CPU. The host draws the terrain with fs(canvas, { view }), then calls height([u, v]) for the height under the cursor: a plain number, from the same code at f32 precision, with no read of the canvas (surface §64).

Runs on WebGPUWebGL2CPU tier

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: one helper on the CPU and the GPU",
"blurb": "A terrain `height` function that the fragment entry draws on the GPU and the host calls on the CPU. The host draws the terrain with `fs(canvas, { view })`, then calls `height([u, v])` for the height under the cursor: a plain number, from the same code at `f32` precision, with no read of the canvas (surface §64).",
"renderable": false,
"reason": "no entry point"
}
*/
class View {
size: vec2;
}
declare const view: uniform<View>;
// An ordinary exported function: the fragment entry calls it on the GPU, and a host that imports
// the module calls it on the CPU.
export function height(p: vec2): f32 {
return 0.5 + 0.25 * sin(6.2831853 * p.x) * cos(6.2831853 * p.y);
}
@fragment
export function fs(@builtin("position") p: vec4): vec4 {
const h = height(p.xy / view.size);
return vec4(h, h, h, 1.);
}
// Call a shader's helper on the CPU, and draw with the same function on the GPU (surface §64).
//
// `height` is an ordinary function of the module. The draw runs it for each pixel on the GPU;
// the host calls it on the CPU, at `f32` precision, for the one value it needs.
import { fs, height } from './host-helper.shade.ts';
/** Draw the terrain into `canvas`, and return the height under the pixel `cursor`. */
export async function run(
canvas: HTMLCanvasElement | OffscreenCanvas,
cursor: readonly [number, number],
): Promise<number> {
const { width, height: rows } = canvas;
await fs(canvas, { view: { size: [width, rows] } });
// The draw computed this pixel at its centre, so the host asks for the same point.
return height([(cursor[0] + 0.5) / width, (cursor[1] + 0.5) / rows]);
}

Both files are the compiler's own at commit 91c2fe31, from the examples directory.

Module on GitHubHost file on GitHub

Edit this page Report a problem