@group(0) @binding(0) var<storage, read> a: array<f32>; // init=rand() count=N
@group(0) @binding(1) var<storage, read_write> out: array<u32>; // count=N/256 show
@group(0) @binding(2) var<uniform> params: Params; // init=N
@group(0) @binding(3) var img: texture_storage_2d<rgba8unorm, write>; // size=512x512
WebGPU compute playground
Write WGSL compute shaders and run them on your GPU — compile errors on their lines, buffers set up from the @group/@binding declarations, a pass script for dispatches, loops and uniform writes, results read back into tables and plots, GPU timestamps, and nine examples with lessons from invocation IDs to a parallel scan, tiled matrix multiply, atomics, bitonic sort, particles and a Mandelbrot set.
Added
How to use it
WebGPU lets a web page run programs on the graphics card — not only to draw, but to compute. This page is a workbench for the compute side: write a WGSL compute shader, say how big the buffers are and what’s in them, dispatch it, and look at what came back.
It’s the companion to the shader playground, which runs WebGL fragment shaders for pictures; this one is about general-purpose GPU work, the kind CUDA and OpenCL are used for, in the browser.
How to use it
Examples load with one click, each with a short lesson beside it. I wrote them for this page:
-
Invocation IDs — every invocation writes down its global, local and workgroup ID, so you can see how a dispatch is laid out.
-
Vector add — one invocation per element, checked bit for bit against the CPU.
-
Parallel reduction — summing a million numbers with a tree in workgroup memory and barriers.
-
Prefix sum (scan) — Hillis–Steele within a workgroup, then the block totals, in three passes.
-
Matrix multiply, naive vs tiled — the same product with and without 16×16 tiles in shared memory, timed side by side.
-
Histogram with atomics —
atomicAddon global counters against per-workgroup counters merged at the end. -
Bitonic sort — 136 dispatches with a uniform buffer rewritten before each, driven by nested loops in the pass script.
-
Particles — a compute pass moves 20 000 particles and a render pass draws them from the same buffer, every frame.
-
Mandelbrot — one invocation per pixel, written into a storage texture.
The WGSL editor compiles as you type once the GPU is up; errors and warnings from the browser’s compiler are marked on their lines (click one to jump to it).
Buffers come from the shader. Every @group(g) @binding(b) var<storage> or var<uniform>
becomes a buffer, sized from its type — the page works out the WGSL memory layout, including the
padding in structs, and shows each field as a column in the results. A comment after the
declaration sets it up:
init is an expression in i (the element) and c (the field within it) with rand() and
randint(a,b) (seeded, so every run gets the same numbers); json=[…] gives exact values;
same=other binds one buffer twice (for instance read-write for compute and read-only for a
vertex shader). The Buffers and bindings table edits these comments for you.
The pass script says what to run: dispatch main N/64 (workgroup counts are rounded up),
write params j, k, copy, clear, for and repeat loops, animate for something that runs
every frame, draw vs fs 6, N for a render pass, and check to compare the results with a CPU
reference. Under it, the page works out how many workgroups and invocations each dispatch makes
before anything runs. The full list is on the How GPU compute works tab.
Results are read back after the run: a table of every element (paged), a plot of any column, min / max / mean / sum, and CSV or JSON downloads. Storage textures are shown as images and can be saved as PNG. Timing uses the GPU’s timestamp queries when the adapter offers them, and wall-clock time per dispatch when it doesn’t.
The How GPU compute works tab explains workgroups and invocations, the address spaces (function, workgroup, uniform, storage), barriers and uniform control flow, atomics, memory layout, and your GPU’s limits.
Share link (at the top) puts the shader and the script in the link.
Browser support
WebGPU is on by default in Chrome and Edge 113 and later on Windows, macOS and ChromeOS, and on
Android from Chrome 121; in Safari 26 (macOS, iOS and iPadOS 26); and in Firefox 141 and later on
Windows, and 145 and later on Apple-silicon Macs. In older Safari it is under Develop → Feature
Flags, in other Firefox builds dom.webgpu.enabled in about:config, and on Linux Chrome may need
chrome://flags/#enable-unsafe-webgpu. Support changes quickly, so if this page says WebGPU is
missing, check your browser’s release notes.
Without WebGPU the page still opens: you can edit shaders and scripts, and the buffer table, the dispatch counts and the script checks work, but nothing runs.
Timestamp queries need the timestamp-query feature; browsers round the values (Chrome to
100 µs unless its WebGPU developer features are switched on). Samplers and sampled textures
aren’t supported as bindings here, only buffers and 2-D storage textures.
Feedback is a gift. Something to improve, a feature to add, or a bug? Tell me.
Runs entirely in your browser; nothing you type leaves this page.