I'm far from convinced that shadertoy demonstration is correct: If you set the number of bits to 1, the dithered version is clearly far too light, which is exactly what happens if you dither in gamma-encoded space rather than linear space.
It gets much worse if you uncomment the SHOW_CORRECT define since the data is then being transformed back to SRGB before being quantised, which quite heavily skews the probability of which code point will be selected in favour of the lighter colour.
Increasing the number of bits hides the effect somewhat by making more code points available. But because they're distributed in gamma-encoded rather than linear-encoded space, it's still not correct to assume that a 50/50 pixel mix of two adjacent code points will appear the same as the colour numerically halfway between them, unless you're making that judgement in linear space.
The mistake the shadertoy is making is transforming the data to sRGB before quantising. Both dithering and quantising should be done in linear space (which is non-trivial since in linear space the codepoints aren't linearly distributed any more) - otherwise the dither function's triangular distribution is skewed by the sRGB transform.
It gets much worse if you uncomment the SHOW_CORRECT define since the data is then being transformed back to SRGB before being quantised, which quite heavily skews the probability of which code point will be selected in favour of the lighter colour.
Increasing the number of bits hides the effect somewhat by making more code points available. But because they're distributed in gamma-encoded rather than linear-encoded space, it's still not correct to assume that a 50/50 pixel mix of two adjacent code points will appear the same as the colour numerically halfway between them, unless you're making that judgement in linear space.
The mistake the shadertoy is making is transforming the data to sRGB before quantising. Both dithering and quantising should be done in linear space (which is non-trivial since in linear space the codepoints aren't linearly distributed any more) - otherwise the dither function's triangular distribution is skewed by the sRGB transform.