Loading assets, please wait...
Understanding how dithering works, visually.
tap/click the right side of the screen to go forward →
I’ve always been fascinated by the dithering effect. It has a unique charm that I find so appealing.
← tap/click the left side to go back
I was even more amazed when I learned how dithering works.
← or use arrow keys to navigate →
Look closely, and you’ll see this animation is made of alternating black and white pixels.
But these black and white pixels are specifically arranged to create the illusion of multiple shades.
That’s what dithering does: it simulates more color variations than what are actually used.
Here, it uses black and white to give the impression of multiple gray shades.
To me, dithering is about creating the most out of what we have, and that's what amazes me the most!
It inspired me to learn more about it, and now I want to share what I’ve learned.
Please note that this is just part one out of three, so I’ll only scratch the surface here.
I’ll go deeper in the next parts, which will come soon. Stay tune!
First, let’s explore the dithering basics with this grayscale image example.
A grayscale image has various gray shades, from black to white.
Imagine a display that only shows black or white pixels, no grays. We must turn some pixels black and others white—but how?
One way is to map each pixel to the closest available color.
Pixels darker than medium gray turn black and lighter ones turn white.
This splits pixels into black or white groups.
However, this creates a harsh image with abrupt black-white transitions.
Shadow details vanish as gray pixels become fully black or white.
Dithering fixes this by selectively pushing some pixels towards the opposite color.
Some light gray pixels that are closer to white turn black.
Likewise, some dark grays turn white.
And it's done in a way that produces special patterns which simulate shades by varying the black-and-white pixel densities.
Denser black pixels are used in darker areas, while denser white pixels are used in lighter ones.
Next question: How are these patterns generated?
One simple dithering method, known as ordered dithering, uses a threshold map.
A threshold map is a grid of values representing brightness levels, from 0 (darkest) to 1 (brightest).
To dither, we compare each input pixel’s brightness to a corresponding threshold value.
If a pixel’s brightness exceeds the threshold (it’s brighter than the threshold), the pixel turns white. Otherwise, it turns black.
Repeating this for all pixels gives us the black-and-white dither patterns.
The threshold map is designed to output patterns where the black-and-white pixel density matches the input image’s shades.
So brighter input produces patterns with more white, while darker input produces more black.
These black-and-white density variations are what create the illusion of gray shades when viewed from a distance.
To dither larger images, we extend the threshold map to match the image size and follow the same principle:
Compare each pixel’s brightness to the threshold map, then turn it black or white accordingly.
The image now uses only two colors, but its overall appearance is preserved.
The variations in shades are now replaced by variations in black/white pixel density of the dithering patterns.
And that’s how dithering works in a nutshell: it replicates shades with fewer colors, which are strategically placed to maintain the original look.
I find it a bit ironic how I used to think dithering ‘adds’ a cool effect, when what it actually does is ‘remove’ colors!
That's all for now! We’ve reached the end, but there’s still a lot more to explore.
For example, we haven’t explored the algorithm to create a threshold map. (spoiler: there are many ways!)
There’s also another algorithm called error diffusion, which doesn’t use a threshold map.
Each algorithm creates a distinct, unique look, which I believe deserves its own article.
And that's why I decided to break this series into three parts.
In the next part, I’ll dive into various algorithms for creating threshold maps.
In the final part, I’ll focus on the error diffusion algorithm.
We'll dive even deeper into dithering's mechanisms in these next 2 parts, so stay tuned!
Thank you for reading!
visualrambling.space is a personal project by Damar, someone who loves to learn about different topics and rambling about them visually.
If you like this kind of visual article, please consider following me on X/Twitter and sharing this with your friends.
I'll keep creating more visual articles like this!
https://x.com/damarberlari
_blank
Topics covered: Three.js, WebGL, dithering, visualization, interactive learning