why do the formats like JPEG are converting color by raising it to (1 / 2.2), isn't our task is to see (0.5, 0.5, 0.5) (gray) and not (0.72, 0.72, 0.72) (light-gray)?
that's because historically monitors (CRT monitors) used to display images with gamma. Gamma, basically said, consisted in doubling the input voltage of these monitors. The goal was to increase brightness onscreen in a non-linear fashion and the value of this non-linear increase was settled at 2.2, which coincidentally (at the time) nearly matched the way humans perceive brightness (in other words it became possible for humans to distinguish darker and brighter colours better on a CRT monitor).
So jpeg formatting encodes -or if u prefer- stores the picture data by gamma correcting them -that is- jpeg applies the inverse gamma value (pow(1.0/2.2)) to each picture colour value, (it makes the picture brighter when it saves) because when this picture is displayed on a CRT monitor, this monitor will automatically invert the picture colour value. This way we get to see the picture at the colour values which the “artist/author” intended for us to see it at.
The other way to say all this is like this:
Let's say Jpeg didn't do anything to our picture.
If author creates picture with colour value (0.5, …) that means this is what the artist wants us to see (0.5, …).
And when the monitor applies gamma (pow(2.2)) to this colour value, 0.5 becomes 0.22, so you see this would be a darker value than 0.5 (not what the author wants us to see).
Therefore Jpeg gamma corrects 0.5 and stores it at 0.72 (pow(1.0/2.2)) this is a brighter value than 0.5;
so finally when the monitor displays this, it applies gamma to 0.72 and therefore drops it to 0.5, which is what the artist wants us to see.
Another question. If I have a texture and I don't know whether the first step was applied (i.e raising to (1 / 2.2) power) or not, should I apply the conversion to linear space? I'm using DirectX and WICTextureLoader, but it doesn't load my image in *_SRGB format. I have an option to force it to do so, but I'm not sure is that correct.
If you are coding a game, you should offer the user/player in your game Menu Graphics Settings the option:
I think you have seen this in some games right ?
This way, you can load your textures and apply gamma correction to them (or not) depending on the user's choice.
Another way to do this is:
- you load your textures without applying gamma correction
- render your scene but in the final pixel shader there you apply final gamma correction:
// pseudo
void pixel_shader( )
{
....
float4 final_col = bla bla bla....
final_col = pow(final_col.rgb, vec3(1.0/gamma)); // <-- do gamma correction here
return final_col;
}
You can also use this method to work out if gamma correction was already applied by WICTextureLoader (or else), but I leave it to u as an exercise to work out, dinner is calling me ?
That's it … all the best ?