0

(english is not my native tongue and it's pretty late).

I am facing a problems for some days and, after many not successfull attemps, I decided to come here to have some help or at least a direction.

We will talk about dithering and color banding. I will not try to explain here what are these, I will just assume that the reader already knows.

Ok, let's start with a picture

Image without dithering

On this image, there is no dithering. Color bands are easy to see, if not on the wall at least on the floor. Because I am generating this image, I do have access to higher precision for each pixel during the generation. If a channel is an integer from 0 to 255, I do have access to values likes 5.24 (the important thing is ".24" - this is what I mean by a "higher precision"). My original idea was to use a noise based on the pixel's position on screen. If we assert that the noise yield values between 0 and 1, for 5.24 the algorithm would looks like

if ( noise(x,y) < 0.24 ) color = 6 else color = 5

I was also using a "white noise" and I obtained this result image with dithering, using white noise

It's a lot smoother, but we get a very high noise. Plus, there is still color banding and this will be the problem I have. By replacing the white noise by a "blue noise", I get this last image

image with dithering, using blue noise

Which is a lot better for the noisiness of the resulting image but ... there are still color bands.

I tried to figure out why. I think it's because I use what I would call a "linear split" or "linear gradient" or "linear interpolation" ... or "linear" something, but it's linear. It the formula I already gave

if ( noise(x,y) < 0.24 ) color = 6 else color = 5

If it's not 0.24 but 0.5, it means a 50/50 mix of (5,5,5) and (6,6,6). However, such and image will appear closer to (6,6,6) than to (5,5,5). Somehow, I think that it's wrong to think that the step between (0,0,0) and (1,1,1) is the same than the step between (200,200,200) and (201,201,201). I think it shouldn't be thought as an addition but as a ratio. And the formula above doesn't really take the "5" into account (it will behave the same way for 5.24 and 200.24).

I don't know if I explain myself well, and it's already really late.

To summerize, I am looking for a formula taking into account not only the ".24" part not only the position of the pixel but also the "5" part.

I think that there is an exponential somewhere (because there is always exponential in optic) and that the result will depend on the monitor (and what I am looking for is more related to cymk than to rgb).

But, still, is there something I can do ? Is there a name to this "non-linear increase of the value of the color" ? Is there something I can ask to google ?

Thanks a lot.

Bubuche
  • 33
  • 3
  • "non-linear increase of the value of the color" is gamma the term you are looking for? https://www.cambridgeincolour.com/tutorials/gamma-correction.htm – Nathan Wride Feb 27 '20 at 04:17
  • Wow. I don't know what is the more stunning, if it's the fact the page looks like it was written for me or if it's the fact I didn't identified that myself sooner. Yes, I think it's exactly that. I never understood what was gamma exactly. I will try to use that to produce the correct formula in the shader. Thanks a lot ! – Bubuche Feb 28 '20 at 02:50
  • I'm glad that might be useful. If you use GLSL as your shading language then this page has more specific examples (but I'm sure you can turn it into whatever shading techniques you are using): https://learnopengl.com/Advanced-Lighting/Gamma-Correction – Nathan Wride Feb 28 '20 at 02:53
  • I'll gladly take a look at it, because the problem is still not solved. I tried a lot of things but never came up with anything satisfying. For example there is the problem of scaling. When I was working with RGB, I was upscaling the value fo [0, 255]. But with gamma, it's not clear. And I think I messed up anyway. I am still working on it. So: I gladly accept this link. – Bubuche Mar 01 '20 at 03:20

0 Answers0