Home‎ > ‎

24-bit Dithering

posted 8 Sep 2011, 12:45 by Burton Radons   [ updated 8 Sep 2011, 13:34 ]
A widely-held misconception is that 24-bit colour (16.7 million colors) is enough to make gradients imperceptible to the human eye. This may be correct if your gradients are red, green, and blue. But any more complex gradient, or any compositing of gradients, will very quickly become visible and annoy the hell out of anyone who can see it.

Correcting for this in computer graphics is kind of stupid easy. Take a texture, fill it with random values. When you are about to return the color from the shader, do this:

float4 output;
output.xyz += (tex2D(RandomSampler, ScreenPosition.xy * Scale).xyz * 0.5) / 256;
return output;

Where "Scale" is some factor that splats the texture evenly over the entire screen. This randomly pushes components up or down half a 24-bit RGB boundary, so that when it's subsequently rounded, it acts as a dither. Here's an example of the result:

The banding on the green is harder to see (as it's one of the primary RGB colors, and so is closer to the ideal) but it's certainly there; these are both very close to ideal conditions for gradients that minimise the error, and to me they're plainly visible. Normally you'd need to do all sorts of fancy tricks to hide patterns in the dither or to avoid a weird feeling when the camera moves that the screen is covered in dust. But because this is so subtle, you don't need to do anything else. One step does it all. Five minutes to implement.

(Yes I'm working on The Nut, I just saw a post on The Witness blog I wanted to comment on.)