0/ 1700/ /3

The Origin of Gamma Space


What we are going to talk about next is related to the post-processing effects and the adjustment of colors. Before starting the main contents of the specific post-processing effects, we need to understand some basic knowledge, one of which is related to the final output display of colors. Next, we will learn about Gamma Space and Linear Space, including the origin of Gamma Correction, the specific application of Color Space in project development, Unity and Unreal engines.


We need to clarify a concept in the beginning: the current discussion on Gamma Space is based on the limited grayscale budget. The specific content will be explained in more detail later.

CRT Display Theory

In the not-so-distant past, the mainstream display at that time was the CRT (Cathode-ray tube) display, the full name of which is the cathode ray tube display:


(CRT Monitor)


For a CRT display: double the voltage, the brightness does not double. The output brightness and voltage are not linear, and the brightness increase is approximately equal to the 2.2 power of the voltage increase, so 2.2 is called the Gamma value of the CRT display, and the color of the CRT display is said to be in the Gamma2.2 space.


Brightness and Voltage Formula


When the voltage changes linearly, compared to the real world, the brightness of the CRT display changes slowly in the dark area, resulting in a wider range of dark data and a darker overall picture.



And our goal is to see the normal brightness similar to the real world. Since the CRT display is in the Gamma 2.2 space, the brightness of the picture we input to the display needs to balance the influence of Gamma 2.2. This operation is called gamma correction (Gamma Correction), which is actually approximately equivalent to performing a 0.45th power operation so that the color is in the Gamma 0.45 space:


Gamma Correction


This allows the color to be restored to resemble the color in real physical space:

Theory of Grayscale Perception of the Human Eye

On the other hand, in the real physical world, if the light intensity increases from 0 to 1, then the brightness increases linearly with it. But the human eye perceiving brightness is not linear. This point is demonstrated in the Weber-Fechner law: people’s perception of external stimuli is not linear, the increase of the sensory quantity lags behind the physical quantity, the physical quantity grows in geometric progression, and the psychological quantity grows in arithmetic progression. That is: when the brightness perceived by the human eye increases by one level, the light intensity actually increases several times.



With a simple mathematical simulation of this phenomenon, it can be considered that people’s psychological perception of brightness is similar to the Gamma 0.45 space curve:


It can be seen that people are more sensitive to the perception of darkness. For example, in the same room, lighting in the dark and turning on a light after turning on a hundred lights, give people a completely different feeling of brightness change. Although in the real physical world, the amount of light intensity increases is the same.


Today’s mainstream pictures are 8 bits per channel, so each channel will have 256 grayscales, and the number of grayscales is relatively small. Because people are more sensitive to dark perception, we need more grayscales to store darker brightness. According to the corresponding relationship in the figure, it is assumed that the brightness of the light intensity in the real physical space is 0.2, and the human eye feels it as the brightness of 0.5, and this data is taken as the 128th grayscale (the middle grayscale). For the brightness perceived by the human eye, we equally divide the number of gray levels, but for the real physical space, the number of gray levels allocated in the 0~0.2 light intensity interval is more.


In this way, the grayscale is allocated. For the brightness of the light intensity of 0.2 in real physical space, the human eye perceives it as the brightness of 0.5, and the brightness perceived by the human eye is recorded as data. The brightness perceived by the human eye as 0.5 is transmitted to the display for display. For the CRT display, the voltage of 0.5 is adjusted by Gamma 2.2, which just shows the brightness of 0.2, which meets the needs of human vision. This is also the mainstream view on the generation of the Gamma color space: a wonderful coincidence, the error of the CRT monitor matches the perception of the human eye. In fact, the transformation of the human eye’s perception curve of brightness may be more complex, not as simple as the Gamma0.45 space curve. It may be due to this coincidence that a relatively simple and feasible method has been extracted to simulate the human eye’s perception curve of brightness.


Therefore, even if the current display voltage and brightness are basically linear, this rule is still followed, and the display Gamma value is set, the purpose is to display more brightness in the dark area so that the gray level of the dark area perceived by the human eye is equal to The number of gray levels in the bright area.


However, with the advancement of technology, one day each channel will be 32-bit so that each channel can have 4294967296 grayscales. With such a huge number of grayscales, the brightness that can be displayed is sufficient, so there is no need for Gamma. The corresponding brightness can be obtained by directly displaying the stored result. This is the premise mentioned at the beginning of this article: the grayscale budget is limited, and a reasonable allocation is required to ensure the brightness range.


In order to match CRT monitors, so that pictures can be displayed on monitors with 8 bits per channel without conversion, HP and Microsoft designed a Standard Red Blue Green color space (sRGB color space) in 1996. Most image files these days are in this color space.


The sRGB color space corresponds to the space where Gamma0.45 is located, which is equivalent to performing a gamma correction on the color of the physical space. The color in the physical world is stored in the space where Gamma 0.45 is located. After adjustment by the monitor Gamma2.2, the result displayed on the real device is consistent with the color of the real physical space.


In this section, we introduce two mainstream views on the origin of Gamma Space, and understand the corresponding calculation methods and practical significance behind them. In the next section, we will talk about how it affects our work, and how we can apply it rationally.

Linear Space Workflow

Gamma Space and Linear Space

Due to the presence of Gamma Correction, we have a little trouble with the calculations in the render. For example, there is a nonlinear input of an sRGB image, and then the operation is performed in a linear space, and the final output result will deviate from the desired result.


Because the physical laws of the real world are calculated in linear space, the calculation in Shader is also calculated in linear space. For example, according to the previous curve, the brightness of the actual physical space light intensity is 0.2, and the human eye perceives it as brightness of 0.5. The results obtained by calculating according to 0.2 and calculating according to 0.5 are naturally different.



Lighting Display under Different Spaces in the Unity Engine

Therefore, in order to ensure a more realistic and accurate restoration of the color of the real physical world, a better production process is to unify the input, calculation, and output in a linear space, then perform Gamma Correction and finally display it on the monitor.


First, we need to ensure that the input data is in linear space. For sRGB textures, we need to perform Remove Gamma Correction (perform a 2.2 power operation) to bring it back to linear space.


Next, perform operations through Shader, and this part of the calculation is in linear space.


Then, Gamma Correction is performed on the result, which is finally output through the display. This gives a result that is close to the real world.


Let’s take the grayscale value of 1 as an example, assuming that after the Shader operation, the output result is 0.9 times the input result.



If it is located in Linear Space, after Remove Gamma Correction value is 1, then the calculate value in Shader to be 1*0.9=0.9, then perform Gamma Correction 0.9^0.45=0.95, and finally display as 0.95^2.2=0.89.


If it is under Gamma Space, the calculated value in Shader is 1*0.9=0.9, and it is displayed on the display: 0.9^2.2=0.79.


It can be seen that the rendering result in Gamma Space is dark. The rendering results in Linear space are a bit brighter.

In Unity

The choices for Linear Space and Gamma Space are located in Project Settings->Player->Color Space:


If Gamma Space is selected:

Unity will not do any processing on input and output. The Remove Gamma Correction and Gamma Correction showed in Figure 7.2 will not happen. If necessary, you need to implement it manually.


If Linear Space is selected:

For sRGB textures, Unity automatically performs Remove Gamma Correction before texture sampling. There is no such step for Linear textures. Before output, Unity will automatically perform Gamma Correction and then let the display output.


So, for a texture, we need to tell Unity the type and color space of the texture:


Some special texture types are Linear Space by default, such as Normal Map, Light Map, etc.


For the Default type of texture, there is an sRGB option. If checked, it means it is in Gamma 0.45 space; if it is not checked, it means it is in Linear Space.


In addition, under Linear Space, the color input in Shader Lab will be defaulted to sRGB color, and Remove Gamma Correction will be performed automatically. For the vertex color attribute data, we need to manually perform Remove Gamma Correction processing.


Sometimes you may need to make a Float variable also remove Gamma Correction, then you need to use the [Gamma] prefix in ShaderLab.


Mobile support: On Android, Linear is only supported on OpenGL ES 3.0 and Android 4.3 and above, and only Metal is supported on iOS. With the development of hardware equipment, more and more projects choose to work under Linear Space to pursue more realistic effects


In Unreal


(Unreal Default Lighting Display)


For Unreal, the principle is the same.


There are sRGB options on the Details page of the relevant Texture:


Similar to Unity represents the storage color space of the image.


Correspondingly, when performing image sampling, you need to select the corresponding sampling type:

  • Color type, indicating that the sampler samples the image in the sRGB color space.
  • Linear Color type, indicating that the sampler samples the image under Linear Space.



In different color spaces, the effect is different (a parallel light is added):


It can be seen that if sRGB is not checked, that is, if this image is treated as an image in a linear space, the result will be brighter. Compared with Unity, Unreal’s settings are more convenient, and Unreal can also set the corresponding space for color input:


With the ever-increasing requirements for rendering, with the advent of physically-based rendering (PBR) with more realism, in order to obtain more accurate calculation results, rendering calculations in Linear Space has been gradually adopted by more teams. The two engines of Unity and Unreal also support the Linear Space workflow well. Developers should understand the Linear workflow and understand how data input, calculation, and output need to be changed. Only in this way can the accuracy of the data calculation be guaranteed.

Screen Post Processing Effects Series

Screen Post-processing Effects: Radial Blur and Its Implementation in Unity

Screen Post-processing Effects: Silhouette Rendering and Its Implementation in Unity

Screen Post-processing Effects: Depth of Field (DOF) and Its Implementation

Screen Post-processing Effects: Streak effect in the Lens Flare effect and Its Implementation

Screen Post-processing Effects: Real-time Glow and Bloom and Its Implementation

Screen Post Processing Effects Chapter 6: Dual Blur and Its Implementation

Screen Post Processing Effects Chapter 5: Kawase Blur and Its Implementation

Screen Post Processing Effects Chapter 4: Box Blur and Its Implementation

Screen Post Processing Effects Chapter 3: Algorithm of Gaussian Blur and Implementation Using Linear Sampling

Screen Post Processing Effects Chapter 2: Two-Step One-Dimensional Operation Algorithm of Gaussian Blur and Its Implementation

Screen Post Processing Effects Chapter 1 – Basic Algorithm of Gaussian Blur and Its Implementation


That’s all for today’s sharing. Of course, life is boundless but knowing is boundless. In the long development cycle, these problems you see maybe just the tip of the iceberg. We have already prepared more technical topics on the UWA Q&A website, waiting for you to explore and share them together. You are welcome to join us, who love progress. Maybe your method can solve the urgent needs of others, and the “stone” of other mountains can also attack your “jade”.


UWA Website:

UWA Blogs:

UWA Product: 

Related Topics

Post a Reply

Your email address will not be published.