Framebuffer About

Fifty years of real-time graphics

FRAMEBUFFER

One valley, one ship, eight eras. Every frame on this page is rendered right now, in your browser, with the technique of its time.

Scroll to begin

This page draws everything live with WebGL 2, which this browser doesn't offer. Try a recent Chrome, Edge, Firefox or Safari.

1979

Lines of light

Before memory for a whole frame was affordable, some arcade machines skipped pixels entirely. A vector monitor steers its electron beam like a pen, tracing only the lines it is told to, straight onto phosphor that glows and slowly fades.

There is no resolution to run out of, so edges stay razor sharp. And the fade is why anything that moves leaves a trail. Hiding the lines behind a solid object took extra work, which is why early wireframes often show every edge at once.

This frame Lines are drawn into a buffer that never fully clears. Each frame it fades by the decay you choose, then a blur adds the glow.

In the wild Asteroids Battlezone Tempest Vectrex Star Wars

1985

Four colours at a time

The Nintendo Entertainment System had no frame buffer either. Its picture processor built every scanline on the fly from 8×8 tiles and up to 64 sprites. Each tile could use one small palette: three colours plus a shared background.

Artists painted with palette indices, not colours, so changing one palette entry recolours everything that uses it at once. Gradients were dithered; parallax came from changing the scroll position partway down the screen.

This frame Every pixel is computed as a 2-bit index, and the palette is applied last. Swap it, or show the tile grid.

In the wild Super Mario Bros. Gradius The Legend of Zelda Mega Man 2 Game Boy

1991

Mode 7

The Super Nintendo could take one background, a 1024×1024 pixel map, and rotate and scale it with a matrix. On its own that is just a flat map, turning.

The trick was HDMA, which rewrote the matrix between scanlines so each row was scaled a little more than the one above. The floor seems to recede to a horizon, though the hardware knew nothing about depth. The same channel painted the sky gradient one line at a time, in 15-bit colour.

This frame The ground is a top-down map of the same valley. Turn off per-scanline scale to see what the hardware was really turning.

In the wild F-Zero Pilotwings Super Mario Kart Secret of Mana

1996

Polygons, wobbling

The PlayStation drew textured, lit triangles fast enough for full 3D, using shortcuts you can still recognise. Vertex positions were whole pixels, so models jitter as they move. Textures were spread across the screen without perspective division, so they bend and swim on big polygons.

Lighting was computed at each corner and blended across the triangle (Gouraud shading). Colour was 15-bit, smoothed with a fixed dither pattern.

This frame 320×240, a few hundred large triangles, all three quirks reproduced in the shader. Turn them off one by one.

In the wild Tomb Raider Crash Bandicoot Final Fantasy VII Metal Gear Solid

2004

Programmable light

Once GPUs ran a small program for every pixel, lighting stopped being per-vertex. Normal maps tilt each pixel's surface to fake detail the mesh doesn't have. Reflections give metal and water something to mirror, and fog sells the distance.

And bloom was everywhere: bright areas are blurred and added back, because the screen still couldn't show anything brighter than white. The same hardware made cel shading possible, with light in flat bands and ink wherever depth jumps.

This frame Per-pixel Blinn–Phong, a procedural normal map, sky reflections, height fog and a bright-pass bloom, with no tone mapping.

In the wild Half-Life 2 Doom 3 Halo 2 The Wind Waker Ōkami

2013

Physically based

Hand-tuned highlights gave way to materials described by physical properties: base colour, roughness, metalness. One lighting model behaves plausibly in every scene, and the environment itself lights every surface, pre-filtered for each roughness.

Rendering moved to high dynamic range. Light values can far exceed white, and a filmic curve maps them to the screen, as film or a camera sensor would.

This frame Image-based lighting from the sunset sky, shadow maps, and a clear-coated hull. Set tone mapping to Clip to watch the sky blow out.

In the wild Killzone Shadow Fall Remember Me Ryse Unreal Engine 4

2018

Following the light

Instead of projecting triangles onto the screen, trace rays out of it: into the scene, towards the sun to see whether it is blocked, then off in a random direction to gather light bounced from everything else. Shadows, reflections and coloured bounce light all come from one algorithm.

The catch is noise. A frame can only afford a sample or two per pixel, so real-time ray tracing leans on accumulating samples over time and on denoisers.

This frame The valley is ray-marched as a heightfield and the ship is 20 triangles. One path per pixel per frame; last frame's samples are reprojected while moving. Stop flying to watch it converge.

In the wild Battlefield V Control Minecraft RTX Cyberpunk 2077

2023

No triangles at all

3D Gaussian splatting represents a scene as a cloud of soft, oriented, semi-transparent ellipsoids, usually optimised from photographs. Each frame they are projected to 2D ellipses, sorted back to front and blended.

There are no meshes and no materials. Appearance is stored rather than computed, which is why captures look photographic and why relighting them is hard.

This frame The valley's lighting was baked into tens of thousands of splats, one colour each (real captures add view-dependent colour). Thin them out or shrink them to see what it's made of.

In the wild Kerbl et al., SIGGRAPH 2023 Capture apps Web viewers

What comes next is already arriving

Neural networks now upscale frames, invent in-between frames and compress textures. The next chapter may be learned rather than written. Every chapter so far was a clever answer to the same question: how much light can we afford, sixty times a second?

About this page

Each era is reimplemented from scratch as a live renderer in WebGL 2: there are no screenshots, videos or game assets. All eight share one scene, a valley that repeats every 256 units. That lets a mesh, a ray marcher and a splat cloud agree on the same landscape. Pixel eras draw at their period's resolution; the dynamic resolution scales the rest to keep things smooth.

Built with three.js, TypeScript and Vite; hosted on Cloudflare.

Designed and built by Pablo Pérez — @pablopsoto

Further reading

Back to 1979 ↑