Color in material and vertices in sRGB or linear ?

Started by
6 comments, last by L. Spiro 7 years ago

Hi,
The textures are in sRGB format, so in the shader it's converted to linear and then all calcule are made in Linear and then the output is converted to sRGB.
But now the question is : is material colors and color on vertices should be in sRGB or Linear ?
If they are in sRGB, they need to do a conversion before send to shader.
For the vertices, surely the hardware convert automatically.
What about the clear color of the render target, the clear color param should also be in sRGB and then converted to linear when used to clear the target ?
Thanks

Advertisement
You can always answer all sRGB<->Linear questions by yourself.
Were the colors created by artists through a monitor? In most cases, an artist picks a color that looks good while viewing it through his or her screen, which means it needs to be converted to linear space for your shader work.

This applies to anything an artist sets by eye, which may or may not include the clear color.


Anything that needs a conversion should be converted offline, as long as fidelity permits. The hardware does not convert vertex colors for you. Store them in linear space inside the vertex buffer.

Remember that you are converting back to sRGB at the end of the render, so anything that was already in sRGB will appear washed out/saturated. This should make it obvious where you need to do conversions.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Anything that's computed yourself and generated by code, like precomputed textures, for example: pbs irradiance cubemaps, the splitsum textures etc...are linear.

pbs irradiance cubemaps

I'm not sure about that, since you generate from a cubemap which can be sRGB, surely the generated values will be in sRGB if the cubemap is in sRGB no ?

pbs irradiance cubemaps

I'm not sure about that, since you generate from a cubemap which can be sRGB, surely the generated values will be in sRGB if the cubemap is in sRGB no ?

Given that most people do lighting in HDR now, these cubemaps are generally at least 16bit and typically floating point.

8bit colour: sRGB
11+bit colour: Linear

If you're using 10 bits or less then you don't have enough bits to represent the human colour gamut, so you need to use some kind of gamma encoding that transforms physically-linear colours into a more perceptually-linear space, which has the effect of reducing the number of bits required.

Linear colours MUST be stored with 11+ bits to avoid colour banding.
sRGB colours can get away with just 8 bits.

So if you're the one writing the vertex data that tells you when to use sRGB or not.
If some other tool is generating your meshes, you'll have to experiment to find out which colour encoding they've used. If it's 8bit it should be sRGB, but lots of software is wrong, so you can't assume. If it's R32_G32_B32 data, they might still be using sRGB because art software is weird like that.

The HW doesn't have any magical/free/automatic sRGB decoding for vertices, so you have to do that manually in the shader.
The HW doesn't have any magical/free/automatic sRGB decoding for vertices, so you have to do that manually in the shader.

Ok, so in the shader it's needed to do :


float SRGBToLinear( in float x )
{
  return ( x <= 0.04045f ) ? x * ( 1.0f / 12.92f ) : pow( ( x + 0.055f ) * ( 1.0f / 1.055f ), 2.4f );
}
If you are not in control of your vertex-buffer pipeline, then yes you would have to convert them in the shader.

But usually you are in control over your pipeline (you will have your own proprietary mesh format), so in that case I repeat:

Anything that needs a conversion should be converted offline, as long as fidelity permits. The hardware does not convert vertex colors for you. Store them in linear space inside the vertex buffer.

Make the conversion when you create your vertex buffer offline, as long as fidelity permits (translation: as long as you have enough bits (see Hodgman's replies)).

You only resort to run-time conversions if you either do not have enough bits for precision or you are not in control over the mesh pipeline.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

This topic is closed to new replies.

Advertisement