Loading assets, please wait...
Understanding Threshold Map in Ordered Dithering.
tap/click the right side of the screen to go forward →
Hi! Welcome back to part 2 of my dithering series!
← tap/click the left side to go back
If you missed part 1, please check it out first! I've covered how dithering simulates more colors than actually exist.
← or use arrow keys to navigate →
This part dives into ordered dithering, a method using a threshold map to decide each pixel's final color*.
*Note: This series covers grayscale dithering to two colors only: black & white. Multi-color dithering is possible, but it will not be covered here.
There are many ways to build a threshold map, each creating a unique visual pattern.
I'll guide you through how it works and how it forms those unique patterns.
Please note that this isn’t a technical deep-dive. It’s just a visual exploration of the logic behind ordered dithering.
I personally grasp ideas much better when I can see them visually, so I hope this helps you too!
Let’s start!
First, a quick recap on quantization: the process of reducing colors in an image.
Grayscale images use many shades, from black to white.
Now, imagine our display can only show pure black and white.
We must convert those gray shades into black or white. This is what quantization does.
One way is by rounding: dark shades become black, and bright shades become white.
Another way is by setting a threshold. Anything below it turns black; anything above it turns white.
The threshold controls the quantization output: lower thresholds can turn darker shades white, while higher ones can turn brighter shades black.
Now, imagine using multiple thresholds at once, each with a different value.
Quantizing a single color now gives us a mix of black and white pixels.
The result reflects the original brightness: brighter inputs get more whites, while darker inputs get more blacks.
This is essentially how a threshold map works in ordered dithering.
It converts gray shades into black & white patterns that mimic the original image's brightness.
Now let’s try to apply this map to a full image by tiling it across the entire area.
Our image is now converted to black & white, but something is off. See those vertical line artifacts?
They are formed by the horizontal black & white patterns our map produces.
The problem is that the output directly mirrors the map's layout.
To fix this, we need to rearrange the threshold map.
Introducing: The Bayer matrix.
The thresholds are arranged in a 2x2 matrix, like this.
When applied, it generates this signature cross-hatch pattern.
This pattern keeps black and white pixels apart, preventing unwanted artifacts like those vertical lines.
The result is a uniform dispersion of black & white pixels that blend smoothly into shades of gray.
Now while this looks better, we still have a problem: the transitions between shades are quite harsh.
The issue? With only 4 threshold levels, we only have 4 patterns to represent the entire grayscale shades.
To improve this, we need to increase the number of our output patterns.
Here is a 4x4 Bayer matrix, which has 16 different threshold values.
It's an extension of the 2x2 matrix. Notice how the sequence is similar, just with different starting values.
Like the 2x2 version, it creates a cross-hatch pattern. But now with 16 distinct pattern variations.
These extra patterns allow us to represent 16 unique shades of gray instead of just four.
As a result, we get smoother transitions between shades.
This reduces harsh transitions between shadows and highlights in the final image.
And that’s ordered dithering in a nutshell!
In summary, it uses a threshold map to translate shades into cleverly arranged patterns.
Now you might ask, can we use even more threshold levels? Or, can we arrange them differently?
The answer is yes! The threshold map's arrangement is what creates those unique dithering patterns. Let’s explore a few other ways to arrange them.
This is the pattern coming from an 8x8 Bayer Matrix. With 64 levels, it’s a further extension of the versions we’ve seen so far.
It still has a similar cross-hatch pattern but offers even smoother transitions between shades.
It provides a denser and more detailed gradient, although the difference is fairly subtle.
Now let’s look beyond the Bayer family with this pattern coming from a 8x8 Cluster Dot matrix.
It consists of round dot clusters, quite different from Bayer’s cross-hatching.
It gives the image the classic, familiar feel of a printed newspaper.
Finally, my favorite method: Void and Cluster.
blue noise
The result is a pattern that feels less rigid than the Bayer cross-hatch.
In the final image, this creates a fine texture that blends into grays more naturally.
That’s all for now! There are still some more maps to explore, but we’ll save those for another time.
If you want more examples and details, here are some resources you might want to explore:
• Libcaca study - 2. Halftoning
• Ditherpunk — The article I wish I had about monochrome image dithering
• Robert Ulichney's paper on void-and-cluster dithering
I hope you enjoy what you read so far! In the next part, we’ll look at another dithering method that doesn't use a map at all: Error Diffusion.
Thanks for reading! See you in the next part.
visualrambling.space is created by Damar, someone who loves to exploring new topics and rambling about them visually.
If you like this, please consider following and sharing. I'll keep creating more visual articles like this!
I'm also open for collaborations or commissioned work. Feel free to reach out anytime.
Follow/contact me on:
https://x.com/damarberlari
_blank
https://bsky.app/profile/damarberlari.bsky.social
_blank
https://www.linkedin.com/in/damarpramudita/
_blank
../rss.xml
_blank
mailto: [email protected]
_blank
Topics covered: Three.js, WebGL, dithering, visualization, interactive learning