Chris wrote:The thing that strikes me is that all these values are between 0 and 1. So when applied to the scene, the resulting pixel will only ever be greater than it's original value. As I understand it, dither is essentially a uniform distribution of random values between -1 and +1, so that it hides quantization error and the overall change is 0. By being between 0 and 1, it raises the overall image brightness since values only ever increase. Shouldn't the dither values be between -1 and +1 to avoid raising the overall brightness?

You're right the distribution should be uniform around zero. The reason the values are higher is because the rounding is baked into the value. The full code looks like this:

- Code: Select all • Expand view
`vec4 Dither(vec4 c, float colorscale)`

{

ivec2 pos = ivec2(gl_FragCoord.xy) & 7;

float threshold = DitherMatrix[pos.x + (pos.y << 3)];

return vec4(floor(c.rgb * colorscale + threshold) / colorscale, c.a);

}

The floor() and the colorscale effectively converts this into doing integer math with floating point. If the values in DitherMatrix are balanced around 0 then it needs a +0.5 for the rounding to be correct.

Whether it is actually still uniformly distributed even when taking that into account I'm not 100% sure. This table fiddling was done in the middle of the night by me and Rachael - there's certainly the possibility we did some error when typing in the table.