Some questions about working in 0-255 integers instead of single precision floating point colors I have many objects that store their color values. At the moment I'm storing them as vec4 values, that is four 4-byte values for RGBA, mainly because this is how the shader reads them. I was thinking of storing these colors as a vector or 4 unsigned single-byte integers. Anyway, with storing color values as one byte integers I can have a combination of 255^3, which is 16,581,375.

I have a couple of question about this.

If I store the red color as 128, this ends up being a floating point value of about 0.502, and a color of 129 ends up being a floating point value of about 0.506. My question is whether there is any discernible difference to speak of, either consciously or unconsciously between the intensity of a color being 0.502 or 0.506, or shades in between. Does this depend on the limitations of your graphics adaptor or video display? Or is there simply no discernible difference that one could tell with the eye for a value in between those two?

Further, I have a similar inquiry about things like color changes over time. If for example we use a 0 to 255 value to do a fade to black over a significant period of time, would one integer jumps on the 0-255 scale in terms of brightness, which would result in about 0.004 in floating point on each change, be detectable as opposed to calculating the change in floating point to begin with?
First, a quick correction:


  storing color values as one byte integers I can have a combination of 255^3


You mean $256^3$. There are 256 eight-bit integers (including zero), not 255. But here comes the more fundamental thing you need to understand.


  If I store the red color as 128, this ends up being a floating point value of about 0.502


It doesn't end up being a floating-point value at all: it ends up as an 8 bit (or possibly 10 bit) integer on your display. Whatever extra precision you had in the floats to start with is thrown away when the final colour goes into the framebuffer. So the rest of what I'm going to say shouldn't influence your choice of what to store, because everything will end up as 8 bit colour channels.

Now that doesn't mean there's never any value in using a higher-precision number earlier on. More precision in the intermediate data means you'll get the full precision in your output format. e.g. if you start out with these normalized integers, and you multiply them all by 2 in the shader, you'll only end up with the even-numbered integers in your output: you lost half of your precision.

As for the question you really asked, about visible differences, it's easy to test that in live conditions. Just make a grey colour gradient from $(0, 0, 0)$ to $(1, 1, 1)$ in whatever representation you like (floats or normalized integers) and show it in place of your real computation. If you see Mach bands on your gradient, then yes, you can tell the difference between adjacent intensities. In general, for adults with normal sight and 8 bit-per-channel RGB in common lighting conditions, there is a visible difference in a grey gradient. That doesn't mean there's a visible difference between every adjacent pair: the eye is less sensitive to contrast in red and blue than in green, and less sensitive to changes in hue, so it strongly depends on the colours involved.

However, there are techniques to make the differences invisible most of the time. Check out my answer explaining what sRGB is for on SO for some examples.