Visualizations
103 / 500

103 · Retro

Dither Lab

Seven dithering algorithms race on a moving scene in 1-bit, handheld green, CGA and EGA.

A procedurally painted lake at sunset, with drifting clouds, sun glitter and a passing sailboat, is quantized every frame to a tiny retro palette. Error diffusion snaps each pixel to the nearest palette color and pushes the leftover error onto unvisited neighbors (Floyd-Steinberg, Jarvis-Judice-Ninke, and Atkinson, which passes on only 6/8 of it), Riemersma diffuses along a Hilbert curve with a fading 16-pixel memory, and ordered dithering adds a fixed threshold pattern: a recursive 8x8 Bayer matrix or a blue noise mask grown with the void-and-cluster method. Tonal palettes dither by luminance (pulled halfway toward the frame's equalized histogram, so every shade gets used), color palettes by nearest color, and Adaptive 8 picks its colors from the frame with k-means. The gamma toggle runs everything in linear light (raw sRGB dithering brightens every midtone), and the grid view scores each algorithm by how far its blurred result strays from the blurred original.

Try it. Drag anywhere to move the wipe, and click the chips beside the handle (or press 1 to 7 and B) to change either side, which can also show the original. The buttons switch palette, scene (the lake or a test card with ramps and a spinning sphere), wipe or grid view, sRGB or linear light, pixel size and motion; hover for a magnifier. Keys: P palette, G grid, L linear light, C scene, space to freeze, plus and minus for pixel size.

  • Error diffusion
  • Ordered dithering
  • Void-and-cluster blue noise
  • Hilbert curve
  • Linear light
  • k-means palette

View the source · one module, plus a small shared runtime for sizing, the animation loop and input

Build your own

Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.

Build a dithering playground with JavaScript and the HTML canvas element. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.

Start simple:
- Make a canvas that fills the window. Do all the pixel work on a small offscreen canvas, about 320x200, and draw it scaled up with imageSmoothingEnabled = false so the pixels stay crisp.
- Paint a test image into the offscreen canvas yourself: a sky gradient, a glowing sun, a few rolling hills and a horizontal gray ramp. Smooth gradients are what make dithering interesting.
- Quantize it to two colors, black and white, three ways: plain thresholding at 50%, Floyd-Steinberg error diffusion (push 7/16 of each pixel's error right and 3/16, 5/16 and 1/16 to the row below), and ordered dithering with a recursive 8x8 Bayer matrix.
- Show one algorithm on the left and another on the right of a vertical line you can drag with the mouse, with a label on each side and number keys to pick the algorithms.

Once that works, make it beautiful:
- Add retro palettes: a 4-shade green handheld ramp, the 4-color CGA palette and the 16 EGA colors. For tonal ramps dither on luminance; for color palettes pick the nearest color in RGB and diffuse the error per channel.
- Animate the scene (drifting sun, rippling water) and re-dither every frame, so you can see error diffusion shimmer while the Bayer pattern stays locked in place.
- Run Floyd-Steinberg in serpentine order (alternate direction on each row) to break up the diagonal worms.
- Add a toggle that converts to linear light before dithering, and notice how much darker and more correct the midtones become.

Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as Atkinson's or Jarvis-Judice-Ninke's kernels, a blue noise threshold mask made with the void-and-cluster method, or Riemersma dithering along a Hilbert curve.
PreviousDifferential GrowthOne closed line grows, buckles and folds into brain coral without ever crossing. NextAmbiguous ObjectsPaper tubes that look round on the table and square in the mirror behind them.

Related visualizations

  • Palette CyclingRetro A waterfall, harbor rain and an aurora, animated without changing a single pixel.
  • Wobbly PolygonsRetro A 1990s console renderer that builds every famous glitch on purpose, toggle by toggle.
  • CRT MonitorRetro An emulated electron beam, decaying phosphors and a shadow mask, under a 7x loupe.
  • Space-Filling CurvesMath Hilbert, Peano, Gosper and friends fold smoothly from one order to the next.
  • Hidden in PixelsType and image A treasure map hides in a landscape's lowest bits. Peel the bit planes to find it.
  • Demoparty IntroRetro A one-minute demoscene production, beat-synced to a tune synthesized from code.
  • Through Other EyesType and image A fruit market, a metro map and test plates as dichromats see them.
  • Pixel SortingType and image Glitch-art pixel sorting run live on painted photos, at any angle.
  • Op ArtGenerative art Riley and Vasarely style compositions that ripple, bulge and vibrate.

Use ← and → to move between demos. While the canvas has focus, keys go to the demo instead.

← More from Emergent Mind Labs