What to try
- Step to the next pixel and follow source + incoming error → chosen value.
- Compare Floyd–Steinberg with Atkinson, then inspect a pixel at the right or bottom border.
What to look for: The next decision includes earlier fractional errors. Floyd–Steinberg passes 100% through its stencil; Atkinson passes 75%, and destinations outside the image receive nothing.
How it works
For a left-to-right scan, the stencil sends 7/16 to the next pixel, 3/16 to the lower-left, 5/16 below, and 1/16 to the lower-right. The next decision uses the original signal plus accumulated error. Keeping those intermediate errors signed and fractional prevents premature rounding from biasing the result.
The method is causal: changing one pixel can affect later decisions. Its pattern therefore depends on scan order and edges. Atkinson provides a useful comparison because its six weights of 1/8 sum to 3/4 rather than one, often producing a different balance of detail and tone.
Use it in the Lab
Use Floyd–Steinberg for detailed palette reduction, then inspect whether the diffusion texture supports the image. Try Atkinson when harder tonal separation is part of the intended look.
Limits & distinctions
The grayscale intuition extends to independent RGB diffusion, but levels per channel can produce more than that many total colors. For a strict total palette, use Indexed palette.
Further reading
The Error Diffusion Algorithm
Floyd-Steinberg dithering works by processing each pixel left-to-right, top-to-bottom. When a pixel is quantized to the nearest available palette color, the quantization error (difference between original and quantized) is distributed to four neighboring unprocessed pixels.
Floyd-Steinberg Weights
Error distribution weights: → right: 7/16 ↙ below-left: 3/16 ↓ below: 5/16 ↘ below-right: 1/16 These weights sum to exactly 1.0, preserving overall image brightness.
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const old = pixels[y][x];
const new_ = nearestPaletteColor(old);
pixels[y][x] = new_;
const err = old - new_;
pixels[y][x+1] += err * 7/16;
pixels[y+1][x-1] += err * 3/16;
pixels[y+1][x] += err * 5/16;
pixels[y+1][x+1] += err * 1/16;
}
}Why It Works
The distribution pattern creates organic, noise-like patterns that the human eye interprets as smooth gradations. The key insight is that error is never lost — it is always pushed forward to unprocessed pixels, so the overall brightness and color of regions is preserved even with a tiny palette.
Aesthetic Applications
Used extensively in early computer graphics (Mac OS, Game Boy, newspaper print), Floyd-Steinberg dithering is now prized in algorithmic art for its ability to create rich textures from limited palettes. Combined with intentional palette selection, it produces a distinctive retro aesthetic that is both nostalgic and visually striking.
For a more uniform look, try Bayer (ordered) dithering. For organic textures, Floyd-Steinberg. For artistic control, try Atkinson dithering — it diffuses only 6/8 of the error, creating higher-contrast results.
Articles
Related artworks
Related Lab categories
Sources & references
Guide updated
