Linear rendering refers to the process of rendering a scene with all inputs being linear. Normally textures exist with gamma correction pre-applied to them, which means that when the textures are sampled in a material the values are not linear. If these textures are used in the usual equations for e.g. lighting and image effect it will lead to slightly wrong results as the equations are calculated in a non-linear space.
Linear rendering ensures that both inputs and outputs of a shader are in the correct color space which results in a more correct outcome.
In the gamma rendering pipeline all colors and textures are sampled in gamma space, ie, gamma correction is not removed from images or colors before they are used in a shader. Albeit these values being in gamma space, all shader calculations treat their input as if it was in linear space, and additionally, when writing the shader outputs to memory, no gamma correction is applied to the final pixel. Much of the time this looks acceptable as the two wrongs go some way to cancelling each other out. But it is not correct.
If linear rendering is enabled then inputs to the shader program are supplied with the gamma correction removed from them. For colors this conversion is applied implicitly if you are in linear space. Textures are sampled using hardware sRGB reads; the source texture is supplied in gamma space and then on sampling in the graphics hardware the result is converted automatically. These inputs are then supplied to the shader and lighting occurs as it normally would. When writing the resulting value to the framebuffer, it will either be gamma corrected or left in linear space for later gamma correction; this depends on the current rendering configuration.
When using linear rendering, input values to the shader equations are different than in gamma space. This means that e.g. lights striking surfaces will have a different response curve and image effects will behave differently than in the gamma pipeline.
The falloff from distance- and normal-based lighting is changed in two ways. Firstly when rendering in linear mode, the additional gamma correction that is performed will make a light’s radius appear larger. Secondly lighting edges will also be harsher. This more correctly models lighting intensity falloff on surfaces.
When you are using gamma rendering, the colors and textures that are supplied to a shader have a gamma correction applied to them. When they are used in a shader the colors of high luminance are actually brighter then they should be for linear lighting. This means that as light intensity increases the surface will get brighter in a non linear way. This leads to lighting that can be too bright in many places, and can also give models and scenes a washed-out feel. When you are using linear rendering, the response from the surface remains linear as the light intensity increases. This leads to much more realistic surface shading and a much nicer color response in the surface.
Infinite 3D Head Scan by Lee Perry-Smith is licensed under a Creative Commons Attribution 3.0 Unported License. Available from: http://www.ir-ltd.net/
When performing blending into the framebuffer, the blending occurs in the color space of the framebuffer. When using gamma rendering, this means that non-linear colors get blended together. This is incorrect. When using linear space rendering, blending occurs in linear space. This is correct and gives the expected results.
Linear rendering gives a different look to the rendered scene. When you have authored a project for rendering in gamma space, at first it will most likely not look correct if you change to linear rendering. Because of this, if you move to linear rendering from gamma rendering it may take some time to update the project so that it looks as good as before, but the switch ultimately enables more consistent and realistic rendering. That being said, enabling linear rendering in Unity is simple: It is implemented on a per-project basis and is exposed in the Player Settings which can be located at Edit -> Project Settings -> Player -> Other Settings
When you are using linear rendering, all lighting and textures are linearized, which means that the values passed to the lightmapper also need to be modified. Thus, when you switch between gamma and linear rendering, you will need to rebake lightmaps. This happens automatically when Unity’s lighting is set to auto bake (which is the default).
Linear rendering is not supported on all platforms. The build targets that currently support the feature are:
Even though the desktop platforms generally support linear rendering, in some cases it may be disabled due to graphics driver issues. You can check this by looking at QualitySettings.desiredColorSpace and QualitySettings.activeColorSpace. If the desired color space is linear but the active color space is gamma then the player has fallen back to gamma space. This can be used to inform the user that the application will not look correct for them or to force an exit from the player.
When you are not using HDR, a special framebuffer type is used that supports sRGB read and sRGB write (Degamma on read, Gamma on write). This means that just like a texture, the values in the framebuffer are gamma corrected. When this framebuffer is used for blending or bound as texture, the values have the gamma removed before being used. When these buffers are written to, the value that is being written is converted from linear space to gamma space. If you are rendering in linear mode then all post-process effects will have their source and target buffers created with sRGB reading and writing enabled so that post-processing and post-process blending occurs in linear space.
When using HDR, rendering is performed into floating point buffers. These buffers have enough resolution not to require conversion to and from gamma space whenever the buffer is accessed. This means that when rendering in linear mode, the render targets you use will store the colors in linear space. Therefore, all blending and post process effects will implicitly be performed in linear space. When the backbuffer is written to, gamma correction is applied.
Rendering elements of the Legacy GUI System is always done in gamma space. This means that, for the legacy GUI system, GUI textures should not have their gamma removed on read. This can be achieved in two ways:
It is also important that lookup textures, masks, and other textures whose RGB values mean something specific and have no gamma correction applied to them should bypass sRGB sampling. This will cause the sampled texture not to remove gamma before it is used in the shader, and calculations will be done with the same value as is stored on disk.