How Dithering Works
I wanted to create a minimal animated background for my personal site — something alive but unobtrusive. I knew about noise and dithering, but didn't understand how it actually works. To figure it out, I asked Claude to build an interactive page so I could explore the algorithm step by step. I decided to share the result here, so let's dig in together.
March • 2025
A screen can only emit bright dots — yet we see shades of gray on it. A printer cartridge holds only black ink — yet it prints photographs. The Game Boy displayed 4 colors — yet artists created the illusion of dozens.
All of this is dithering. A trick that makes your eyes see colors that aren't actually there.
What an Image Really Is
Images look smooth and continuous. But zoom in far enough and you'll see they're made of tiny colored squares — pixels.
Наведи курсор, чтобы увидеть значение яркости
Each pixel stores three numbers: how much red (R), green (G), and blue (B) to mix in. Each number ranges from 0 (none) to 255 (maximum). Try mixing them yourself:
To work with dithering, we only need one brightness value. We convert a pixel to grayscale using a formula that accounts for eye sensitivity to different colors: 0.299R + 0.587G + 0.114B.
What if we want to keep only two colors — black and white? How do we make the image still look recognizable?
An Optical Illusion From Two Colors
Here's the key idea: if you place many black and white dots side by side in the right proportion, your eye blends them and sees gray. More black dots — darker. More white dots — lighter. Try it yourself:
This trick is dithering. Newspapers, old computers, and GIF images use it every day. Grab a magnifying glass and look at a newspaper photo — it's made of tiny dots. And the painter Georges Seurat painted entire canvases from thousands of colored dots — chaos up close, beauty from afar.
The Simple Approach: Just Threshold
The simplest way to turn an image into black and white is threshold clipping (quantization). Take each pixel and compare it with a threshold (usually 128): brighter — white, darker — black.
Simple but crude. Try it with different brightness values:
A pixel with brightness 96 becomes black (0), even though it was dark gray. The difference between the original and the result is the quantization error. Apply this clipping to an entire image and smooth gradients turn into ugly stripes. This is called banding.
Градиент (оригинал):
После квантования (2 уровня):
Пиксель со значением 128 → 255. Ошибка: 127
The Smart Approach: Don't Throw Away the Error
Instead of simply losing the error, the Floyd-Steinberg algorithm (1976) does something non-obvious: it passes the error to neighboring pixels that haven't been processed yet.
An analogy: you're a teacher handing out candy. Each student gets exactly 0 or 10 pieces. The first one deserves 7 — you give 10 (3 extra). You subtract those 3 extras from the next students. In the end, the class average is fair!
The algorithm works in three steps:
Step 1: quantize the pixel. Take the current pixel and round its brightness to the nearest available level. With two levels (black/white): if brightness >= 128 — white, otherwise — black.
Step 2: compute the error. Error = original brightness minus the new value. That's what we "lost" during rounding. For example: pixel 96 became black 0. Error: 96 - 0 = +96. We lost 96 units of brightness!
Step 3: pass the error to neighbors. Floyd and Steinberg devised exact weights for four neighbors. Processing order matters — we go left to right, top to bottom. So only pixels to the right and below receive the error.
× — текущий пиксель. Числа — доля ошибки, которая распределяется на соседей.
Watch how the error gets distributed step by step:
Pixel * has brightness 96.
It's less than 128, so it becomes black (0).
Error: 96 - 0 = +96
These +96 units of brightness need to go somewhere!
Each neighboring pixel "inherits" part of the error and accounts for it during its own quantization. This preserves the average brightness of the area, and the eye sees the correct tone.
Why exactly 7, 3, 5, 1? Because 7 + 3 + 5 + 1 = 16, and dividing by 16 is a bit shift, which is very fast for a computer. Plus these weights create an ideal checkerboard pattern for 50% gray.
Watch It in Action
Now let's see the entire algorithm at work on a small grid. The numbers inside pixels are their current brightness (accounting for errors received from previous ones). Blue border — current pixel, orange — those receiving the error. Click through and watch:
Входные значения (+ ошибка):
Результат:
Шаг 1/36: пиксель [0, 0]
Значение: 0 → чёрный (0). Ошибка: 0
The Full Pipeline
Dithering is a four-step pipeline, each step transforming the image:
- Original — full-color RGB image
- Grayscale — convert each pixel to a single brightness value
- Quantization — round to N levels. Banding appears
- Dithering — same quantization, but with error diffusion. Banding disappears
Hover over any stage to inspect pixels up close. You can upload your own photo.
Оригинал
Оттенки серого
Квантование
Floyd-Steinberg
Why It Matters
The idea of "don't throw away the error, pass it forward" turned out to be surprisingly universal. Floyd and Steinberg published it in 1976, and it still works everywhere.
Printing. Newspapers, magazines, laser printers — all use dithering to render shades with a single ink color.
GIF format. Maximum 256 colors. Dithering preserves smooth transitions in animations.
Retro games. Game Boy, NES, early Macs — artists created pixel art masterpieces using dithering.
Screens. E-ink displays (Kindle) use dithering to show photographs on black-and-white screens.
Audio. Audio dithering adds microscopic noise when converting from 24-bit to 16-bit, masking quantization distortion. Without it, quiet sounds come out "dirty."
Neural networks. Weight quantization in neural networks is the same idea: fewer bits, but with error compensation.
In the end, I updated the background of my site with dithering. But what mattered most to me was something else: an interactive tool turned out to be the best way to understand the algorithm and its logic.