Stippling vs Dithering: What Actually Makes the Blue-Noise Look

EFFECT EXPLAINERDESIGNER

Stippling drops dots by density; dithering quantizes a fixed grid. Here's what blue noise changes in each, with kott's exact settings.

01/ ARTICLE

What's the difference between stippling and dithering?

Stippling places dots wherever local tone needs them. Dithering quantizes every pixel of a fixed grid against a threshold map. That's the one-sentence version, and it holds up under scrutiny — because most explanations of "stippling vs dithering" jump straight to blue noise without ever naming the actual mechanical split: a grid, or no grid.

Stippling is a pattern of dots whose local density encodes tone: denser dots read as darker. Nothing about the technique requires those dots to sit on a lattice. In practice they don't, since unstructured placement is exactly what keeps a stippled image from reading as a screen. Ordered dithering works the opposite way, defined by its grid — every pixel gets compared against a threshold value pulled from a small matrix tiled across the image. Change the matrix and you change the look, but the tiling never goes away.

Blue noise complicates this split, and usefully so, because it shows up on both sides of it. Ordered dithering can swap its threshold matrix for a blue-noise matrix and stay a grid method. Stippling can use blue noise to decide where dots go and stay a no-grid method. The table below separates the three results you'll actually run into.

MethodPoint placementVisible artifactBest use
Ordered dithering (Bayer)Fixed periodic gridCrosshatch pattern, moiré on regular subjectsVideo and print — pattern is stable frame to frame
Blue-noise ditheringFixed grid, blue-noise thresholdsFine, even grain, no crosshatchStills where you want Bayer's sharpness without the tiling
Blue-noise stipplingUnstructured (jittered or dart-thrown)Organic, hand-set lookPortraits, foliage, anything a rigid grid makes look mechanical

For how a third family fits into this picture, see Floyd-Steinberg vs ordered dithering. Error diffusion shares dithering's grid but changes the timing of the threshold comparison instead of the matrix.

Why does ordered dithering make a crosshatch pattern?

A Bayer matrix assigns every position in a small tile — 2x2, 4x4, 8x8 — a fixed threshold value, generated recursively: each larger matrix is built from the smaller one via a Kronecker product. Tile that matrix across an image, compare each pixel's brightness to its matrix position, and you get a deterministic, repeatable pattern. The crosshatch isn't a bug. It's the entire value proposition of ordered dithering: the same pixel always gets the same threshold, so the pattern stays dead stable across frames.

kott's own ORDERED / BAYER effect makes this reproducible on a single control set: MATRIX (2X2 / 4X4 / 8X8 / BLUE / BLUE·T), THRESHOLD (0–1, default 0.50), PIXEL (1–12px, default 1), CONTRAST (0.2–3, default 1.0). Hold threshold, pixel, and contrast constant, swap only MATRIX, and you've isolated the one variable that actually causes the crosshatch — the matrix, not the threshold, not the pixel size.

The failure mode is predictable enough. At small pixel sizes, the crosshatch reads as an obviously artificial grid instead of tonal gradation. And if the underlying image already carries a regular pattern — brick, fabric weave, a fence — the two grids beat against each other, producing moiré that has nothing to do with either the photo or the dither you intended.

Want the tradeoff between 4x4 and 8x8 tile sizes specifically — more threshold levels versus a coarser visible tile? That's covered in 4x4 vs 8x8 Bayer matrix.

What does blue noise actually fix?

Blue noise is a mask where points or values spread out with large mutual distances and no periodic structure — the opposite of the Bayer matrix's deliberate regularity. Swap a Bayer matrix for a blue-noise matrix in an ordered-dithering pipeline (the "void-and-cluster" approach), and you keep the same high-frequency detail. The dither still resolves fine tonal steps. But the crosshatch disappears, because there's no repeating tile left to see.

Generating that mask isn't free, though. The classic method blurs a random black-and-white image to find its voids (gaps with too few points) and clusters (gaps with too many), then ranks pixels by how much they need to move — expensive at large sizes. Newer approaches use progressive dart-throwing instead: drop points one at a time, reject any that land too close to an existing point. Brute-force, yes, but fast enough at production sizes with modern optimizations. Either way, the mask gets generated once and reused across every image it touches. That's the whole reason it's practical.

How does a blue-noise stipple algorithm actually work?

kott's STIPPLE effect is the reproducible version of this: SCALE (2–16px, default 3), THRESHOLD (0–1, default 0.50), DOT SIZE (0.5–3, default 1.3). Mechanically, it starts from a grid for performance — cells of SCALE pixels — but jitters each cell's dot center away from the grid position, then gates whether that dot is visible at all using a blue-noise threshold compared against local brightness. Cells in dark areas of the source are more likely to keep their dot. Cells in light areas are more likely to drop it. The result reads as unstructured density variation, not a lattice, even though a grid is quietly doing the bookkeeping underneath.

Fully unstructured stipple methods skip that bookkeeping grid entirely. The BlueNoiseStippling approach precomputes a blue-noise mask via progressive dart-throwing to decide dot positions with no grid at all, then runs Floyd-Steinberg error diffusion as a separate pass to decide dot tone — two stages, one for placement, one for darkness. kott folds both jobs into a single per-pixel shader pass instead. Different mechanism, same goal: a blue-noise stipple is dithering's tone logic applied to dot positions instead of pixels.

When should you use stippling, ordered dithering, or blue-noise dithering?

The right answer depends on who's asking and what the output has to survive. A designer chasing a specific look wants the fastest reproducible settings, full stop. A VJ needs the pattern to survive 60fps motion without swimming. A print or riso maker needs a screen a press operator can reason about and repeat. A photographer wants a treatment that doesn't fight the subject.

  • Ordered / Bayer — video and print, because the matrix is fixed and the pattern is identical frame to frame. Nothing to resample, nothing to crawl.
  • Blue-noise dithering (BLUE) — stills where you want the sharpness of a fine dither without the crosshatch reading as an obvious pattern.
  • Blue-noise dithering, temporal (BLUE·T) — animated and VJ work. kott's BLUE·T matrix mode offsets the same blue-noise mask by a golden-ratio step every frame instead of resampling a fresh mask, so the grain looks alive without visibly crawling. Keeping a dither pattern stable across video frames covers the deeper failure-mode breakdown.
  • Blue-noise stippling — portraits, foliage, anything organic, where even a blue-noise grid still reads as too mechanical against skin or leaves.

What breaks when you pick the wrong one?

Two failure modes come from the source material, not the algorithm. Dithering an already-small or heavily detailed sprite destroys clarity rather than adding texture — there isn't enough resolution left for the pattern to read as anything but noise. And when the two tones you're blending sit far apart in contrast, you need more intermediate steps, not a fancier dither pattern. Reusing the same few dithering patterns at more steps reads better than cycling through every pattern available at once.

Two more come straight from kott's own settings. Resample blue noise independently every frame instead of switching to BLUE·T, and you get visible boiling — the grain looks like it's crawling even though nothing in the source image moved. Push STIPPLE's SCALE too low on a busy source, and adjacent dots merge into a solid texture instead of a legible tonal gradient. The dots stop reading as dots.

Frequently Asked Questions

Is blue noise the same thing as blue-noise dithering?

No. Blue noise is a spatial statistic — an unstructured point or value distribution with no low-frequency clumping and no periodic structure. Blue-noise dithering is one use of it: swapping a Bayer threshold matrix for a blue-noise matrix. Blue-noise stippling is a separate use: placing dots at blue-noise-distributed positions, then running a tone step on top.

Does stippling use a grid at all?

Not the way ordered dithering does. kott's stipple effect starts from a grid for performance (the SCALE parameter sets the cell size) but jitters each dot's center inside its cell and gates visibility per cell with a blue-noise threshold, so the visible result reads as unstructured placement rather than a fixed lattice. Fully unstructured methods like dart-throwing skip the grid entirely and pay a higher generation cost for it.

Why does my dithered animation crawl or flicker?

Static blue noise looks great on a single frame but resamples independently per frame if you're not careful, so the pattern seems to boil. kott's ORDERED / BAYER effect has a dedicated BLUE·T matrix mode that offsets the same blue-noise mask by a golden-ratio step each frame instead of resampling it: same texture, no crawl. Ordinary Bayer dithering never has this problem, because the matrix is fixed and periodic by design.

Which one should I use for a riso print?

Ordered dithering (Bayer, 4x4 or 8x8) for anything that needs a predictable, repeatable halftone screen a press operator can reason about. Blue-noise stippling for a softer, hand-set look on portraits or organic subjects, where the visible grid of a Bayer screen reads as too mechanical against skin or foliage.

Try it

The fastest way to see the difference is side by side, on the same image. Open STIPPLE in the studio with scale, threshold, and dot size preloaded at the settings above, and drop in your own photo.

02/ OUT

Try it in the studio

Every setting described above is a real control. Open your own image and sweep it.

All journal entries