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:
- 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
pNGbchunk 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. - The source, byte for byte the file in the pngine repository. Long files start folded.
- 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.
Where these come from
Section titled “Where these come from”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.
Gradient backgroundA rotating colour gradient from three phase-shifted sines
Shader art (plasma)The classic sine plasma, summed sines through a palette
Spinning shapesSigned-distance polygons, stars and circles that orbit and glow
Procedural normal mappingA bumpy disc lit from a normal derived from a noise height field
Procedural skyboxSky gradient, sun, noise clouds and sunset tint, no texture at all
Procedural noiseFour quadrants: fbm, gradient noise, Worley noise and marble
Color cyclingFour palette-animated patterns cycling through an HSV hue
Resolution-adaptive renderingA grid with a pixel-fixed line width and circles that stay round
Scene transitionsFour scenes and four transitions, both scenes evaluated per pixel
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.
Vertex colorsOne rotating triangle with a colour per vertex, from an interleaved buffer
Wireframe cubeTwelve line segments drawn with line-list topology
Multiple triangles64 instanced triangles seeded by a compute init pass
Sprite renderingAlpha-blended instanced quads, each a procedural SDF shape
UI elementsA mock interface from twelve blended quads and instance_index
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.
Game of LifeConway's automaton on a 128×128 toroidal grid
DiffusionHeat from two moving sources spreading through a Laplacian step
Fluid simulationSemi-Lagrangian advection of velocity and dye on a 96×96 grid
Particle fountain2048 GPU-simulated particles drawn as additive points
Wave simulationThe 2D wave equation on a height field, shaded like water
Reading the source
Section titled “Reading the source”A few things every listing relies on, so they are not repeated on each page:
- Bare identifiers are cross-references.
:pipeline pipelinenames the(render-pipeline :name pipeline …)form; the compiler resolves them document-wide. See References. pngine-inputsis a built-in data source: 16 bytes oftime,width,heightandaspectthe runtime writes each frame through a(queue …)form. Every sample reads it from a WGSLUniformsstruct with those fourf32fields.context-current-textureis the canvas texture for the current frame, andpreferred-canvas-formatthe browser’s preferred format for it.:layout autoin a pipeline asks WebGPU to derive the bind group layout from the shader, and:layout pipeline :group 0on 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.


