Skip to content

Samples

Each page in this section is one small program from pngine’s examples/samples/ directory, written in SJON, the S-expression format pngine compiles: every WebGPU resource (a buffer, a pipeline, a pass) is one form, and the shaders inside the forms are plain WGSL, WebGPU’s shading language.

Every page has the same shape:

  1. The program, running. A PNG the pngine CLI produced from the source. Its pixels are one frame rendered natively (the picture you see before pressing Play), and its pNGb chunk carries the compiled bytecode plus the executor, the small WebAssembly interpreter that turns that bytecode into GPU commands. Press Play and the browser runtime loads that same file into the canvas. The button sits outside the canvas on purpose: pointer input on the canvas belongs to the program.
  2. The source, byte for byte the file in the pngine repository. Long files start folded.
  3. How it works, form by form: what each SJON form declares, what the shaders compute, and links to the part of the WebGPU or WGSL specification that defines the API or language feature underneath.

Running a sample needs a browser with WebGPU. Without it the poster stays and the Play button is disabled; everything else on the page still reads.

This series is pngine’s own numbered sample collection. It grew inside the engine as its test corpus, one program per technique, and it follows the pattern set by the WebGPU Samples gallery (webgpu/webgpu-samples, BSD-3-Clause, © WebGPU Samples Contributors): small, self-contained programs that each isolate one part of the API. Where a page corresponds directly to an upstream sample it says so and links to it; the rest are original programs in the same spirit, and pngine’s ports of the upstream gallery itself live in the engine repository as examples/webgpu_*.sjon.

The numbering (01 to 29, with gaps) is the corpus’s own; the pages below are grouped by technique instead.

Fullscreen shaders

One triangle covers the canvas and the fragment shader does all the work: no vertex buffers, one uniform buffer with time and canvas size.

Vertex data and instancing

Geometry uploaded from the document or seeded by a compute pass, drawn once or hundreds of times from per-instance data.

3D, depth and lighting

A depth texture sized to the canvas under every one; the cube shape generator, back-face culling and per-fragment lighting in the first two, a compute-filled instance buffer in the third.

Compute simulations

A compute pass steps the state each frame through a ping-pong buffer pair, and a fullscreen triangle or a point cloud shows it.

A few things every listing relies on, so they are not repeated on each page:

  • Bare identifiers are cross-references. :pipeline pipeline names the (render-pipeline :name pipeline …) form; the compiler resolves them document-wide. See References.
  • pngine-inputs is a built-in data source: 16 bytes of time, width, height and aspect the runtime writes each frame through a (queue …) form. Every sample reads it from a WGSL Uniforms struct with those four f32 fields.
  • context-current-texture is the canvas texture for the current frame, and preferred-canvas-format the browser’s preferred format for it.
  • :layout auto in a pipeline asks WebGPU to derive the bind group layout from the shader, and :layout pipeline :group 0 on a bind group asks for that pipeline’s group 0.
  • The vertex shader vs(@builtin(vertex_index) i: u32) that appears in most fullscreen samples is the standard oversized-triangle trick: three vertices from the vertex index alone, no vertex buffer, covering the whole clip space so the fragment shader runs on every pixel.

The SJON Reference documents every form; the SJON Syntax guide covers the reader, expressions and lowering.