Shaders, WebGPU & 3D
The GPU pipeline: vertex, fragment, compute.
The CPU draws one thing at a time. The GPU draws millions of pixels at once. A shader is a tiny program that runs in parallel across all of them — and once you grasp that the same function executes simultaneously for every pixel, the whole world of plasma, noise fields and 3D lighting opens up.
The pipeline: vertices in, pixels out
A draw call flows through two programmable stages. The vertex shader runs once per vertex and decides where geometry lands in clip space. The rasterizer fills the triangles, then the fragment shader runs once per covered pixel and decides its color. Both are massively parallel: thousands of cores execute the same shader on different data (SIMD).
The live shader editor
This is the centerpiece. A full-screen triangle is drawn with raw WebGL2, and the
fragment shader below is yours to edit. It recompiles live; if you make a
mistake, gl.getShaderInfoLog shows the exact line. Move your pointer over the canvas
(u_mouse warps the field) and drag the sliders to feed u_scale / u_speed.
Noise: where organic patterns come from
Pure sines give you stripes. The thing that makes shader art look like marble, smoke, or terrain
is noise — a smooth pseudo-random function of position. Value noise (in the demo)
hashes a grid and interpolates; gradient (Perlin/Simplex) noise is smoother. Stack several octaves
at rising frequency and falling amplitude (fractal Brownian motion) and flat math turns
into clouds. Try replacing the sines in the editor with more noise() calls.
GLSL vs WGSL
WebGL speaks GLSL (the editor above). WebGPU speaks WGSL, a newer, Rust-flavored shading language with explicit types and bindings. The same idea, different syntax:
#version 300 es
precision highp float;
uniform float u_time;
out vec4 o;
void main() {
o = vec4(
abs(sin(u_time)),
0.4, 0.8, 1.0);
}@group(0) @binding(0)
var<uniform> u_time: f32;
@fragment
fn fs() -> @location(0) vec4f {
return vec4f(
abs(sin(u_time)),
0.4, 0.8, 1.0);
}WebGPU: the next-generation API
WebGPU is the successor to WebGL — a modern, lower-overhead GPU API modeled on Vulkan/Metal/D3D12. It exposes compute shaders: programs with no pixels or vertices at all, just a grid of threads doing general math (particle simulation, physics, ML inference) directly on the GPU. WebGL never had that.
Milestone announced Nov 25 2025: WebGPU shipped default-on across Chrome/Edge, Firefox and Safari. Chrome since v113 (2023); Safari 26 (Sept 2025); Firefox 141 on Windows (Jul 2025), 145 on Apple Silicon. Gaps remain: Linux, Firefox Android (behind a flag), and importExternalTexture not yet in Firefox stable. Two implementations under the hood: Dawn (Chrome) and wgpu (Firefox).
Scene graphs: you rarely write raw WebGL for 3D
Hand-writing matrices and buffers is fine for a quad; for a lit, textured 3D scene you want a scene graph. Three.js is the foundation; React Three Fiber + Drei wraps it for React; Threlte wraps it for Svelte; Babylon.js is a batteries-included engine. For physics you bolt on Rapier. The scene below is Threlte — declarative Svelte components compiling down to Three.js.
Drag to orbit · scroll to zoom. Rotation uses useTask (delta-based).
Playground: a bare WebGL2 shader from scratch
No libraries, no imports — just a <canvas> and ~40 lines that compile a fragment
shader and animate it. Edit the FRAG string and re-run to see your changes.