Lessons

How GPUs draw a frame, and how engines feed them

Four parts. Pipeline fundamentals run on a small software rasteriser written for this site, which you can pause after any vertex, triangle or pixel. The later parts, on engine-side rendering, lighting and shading and performance, run on your real GPU through WebGPU, falling back to WebGL2 where WebGPU is missing.

Pipeline fundamentals

A software rasteriser written for the site, which you can pause after any vertex, triangle or pixel.

  1. 1The pipeline and the draw callWhat happens between a draw call and the pixels it changes: vertex shading, primitive assembly, clipping at the near plane, culling, rasterisation, fragment shading and the output merger, stepped one vertex, triangle and pixel at a time.
  2. 2RasterisationHow a GPU decides which pixels a triangle covers and what values they get: edge functions on a fixed-point grid, the top-left rule that keeps shared edges watertight, barycentrics, perspective-correct interpolation, and what MSAA samples and what it shades.
  3. 3DepthThe z-buffer and what it really stores: why precision piles up at the near plane, z-fighting and how the near plane, the depth format and reverse-Z change it, and when the depth test runs before the fragment shader: early Z, late Z and the depth prepass.
  4. 4Textures and samplingFrom texels to pixels: nearest and bilinear filtering, mipmaps and how the GPU picks a level from the derivatives across a 2 × 2 quad, trilinear and anisotropic filtering, and block compression (BC1–BC7, ASTC) in brief.
  5. 5Blending and transparencyThe blend equation, premultiplied alpha and why straight alpha leaves fringes, why transparent things need sorting and what goes wrong when they aren't, alpha test against alpha to coverage, and order-independent transparency in brief.
  6. 6How shaders runWaves and warps: one instruction stream for 32 or 64 lanes, what a divergent branch costs, registers and occupancy, and why tiny triangles waste most of their work in 2 × 2 quads.

Engine-side rendering

The real GPU, through WebGPU (WebGL2 where WebGPU is missing); the render-graph, texture-atlas and Nanite lessons run their models on the CPU.

  1. 7The same frame on a real GPUThe pipeline lesson's frame drawn through WebGPU (or WebGL2): adapters and devices, pipelines and why their state is baked up front, bind groups, command encoders and queues, and what happens to a draw call on its way to the GPU, with the D3D12, Vulkan and Metal names for each.
  2. 8Batching and instancingWhy draw calls cost CPU time (and less on D3D12 and Vulkan than on D3D11 and OpenGL), sorting by state with sort keys, merging static geometry, instanced draws, and what each saves. On the real GPU, with the CPU cost measured live.
  3. 9CullingNot drawing what can't be seen: frustum culling with bounding spheres and boxes, occlusion culling with a hierarchical Z-buffer and with occlusion queries, levels of detail, and the frame of latency that last-frame methods add. A city on the real GPU, culled by a model you can step.
  4. 10Render graphsDescribing a frame as passes that declare what they read and write, so the engine can cull passes nobody needs, order them, insert the barriers D3D12 and Vulkan require, and alias transient memory. A small graph compiler you can edit.
  5. 11GPU-driven renderingMoving culling and draw submission onto the GPU: indirect draws (and multi-draw indirect, which WebGPU lacks in core), a compute shader that culls and writes draw arguments, bindless resources, and where mesh shaders fit. Live on WebGPU, with a CPU fallback on WebGL2.
  6. 12Quirky solutions: texture atlases for 2D spritesPacking many sprites into one texture: shelf, skyline, guillotine and MaxRects packers, power-of-two sizes and rotation, bleeding at the edges and why padding and extrusion fix it, and what mipmaps do to an atlas.
  7. 13Quirky solutions: Nanite in briefUnreal's virtualised geometry: clusters of 128 triangles in a DAG of levels of detail, a cut chosen per frame by screen-space error, two-pass occlusion culling, software rasterisation of small triangles in compute, and a visibility buffer written with 64-bit atomics. Why people get excited, and what it costs.

Lighting and shading

The real GPU, through WebGPU (WebGL2 where WebGPU is missing).

  1. 14Forward, deferred and clusteredWhere lighting happens: forward shading and its objects × lights cost, G-buffers and deferred lighting, tiled and clustered light lists, and what each costs in bandwidth, MSAA, transparency and material variety. One scene with up to 256 lights, drawn each way on your GPU.
  2. 15Physically based shadingMicrofacet BRDFs in practice: GGX, Smith and Schlick's Fresnel, the metalness and roughness workflow, energy conservation checked in a white furnace, and image-based lighting with the split-sum approximation. Spheres on your GPU, with the BRDF's lobe and energy computed beside them.
  3. 16Shadow mapsRendering depth from the light (Williams, 1978), why that gives shadow acne and peter-panning, constant and slope-scaled bias, softening the edges with percentage-closer filtering, and cascades for scenes bigger than one map. A sun you can move over the courtyard, with every setting live on your GPU.
  4. 17Post-processingWhat happens between the lit frame and the screen: HDR targets, exposure and tone mapping (Reinhard, a filmic ACES fit, AgX in brief), bloom from a downsample and upsample chain, temporal anti-aliasing and upscaling (jitter, history, clamping, ghosting), and the order the passes run in. A night scene on your GPU with every pass switchable.

Performance and profiling

The real GPU, through WebGPU (WebGL2 where WebGPU is missing), with timings from your machine; the frame-pipeline lesson is a model, the same everywhere.

  1. 18Overdraw and fill rateMeasuring how many times each pixel is shaded, with a heat map on the real GPU: opaque overdraw and the sorting and prepass that fix it, then particles, where no depth test helps and the fixes are fewer and smaller particles, trimmed quads, half-resolution buffers and cheaper shaders.
  2. 19BandwidthRender-target formats and their bytes per pixel, a frame's bandwidth worked out from its passes' load and store ops, framebuffer compression (DCC, AFBC) in brief, and tile-based GPUs, where keeping data on chip is the whole game: WebGPU's loadOp and storeOp, memoryless and transient attachments, and passes that never leave the chip.
  3. 20Timing the GPUWhy a CPU timer around draw calls measures almost nothing, how timestamp queries let the GPU time itself (WebGPU, D3D12, Vulkan, and Chrome's 100 µs rounding), what pipeline statistics count, and what PIX, RenderDoc, Nsight Graphics and Radeon GPU Profiler show and when to reach for each.
  4. 21The CPU–GPU frame pipelineFrames in flight and the CPU running ahead, present modes (FIFO, mailbox, immediate) and swapchain images, where the time from input to photon goes, and how engines cut it: fewer frames in flight, waiting for the swapchain before reading input, Reflex-style just-in-time starts and late latching.

The software rasteriser snaps positions to 1/256 pixel and decides coverage with exact integer arithmetic, so it draws the same pixels in every browser. Code examples are in C++.