1. 程式人生 > >Unity3D Gamma And Linear Space

Unity3D Gamma And Linear Space

參考:https://www.cnblogs.com/murongxiaopifu/p/9001314.html

 

總結:

1. CRT gamma 和 gamma correction

 

上圖中的紅色實心線是在gamma = 2.2的情況下,顯示器實際顯示色彩強度的方式。 這一部分是由顯示器的特性導致的。所以如果圖片不做任何處理,經過pow(2.2)的操作之後顯然會變得更暗,所以gamma校正就顯得很有必要了。而gamma校正要做的事情也十分簡單,即通過pow(1/2.2)將顏色強度提高,也就是上方的紅色虛線,這樣經過顯示器時就會將顯示器的pow(2.2)抵消掉。

CRT gamma 是顯示器做的,pow(x,2.2),x=[0,1],變暗

gamma correction 是為了抵消 CRT gamma 而做的,pow(x,1 / 2.2), x=[0,1], 變亮

 

2.  gamma空間下的紋理格式和FrameBuffer格式

a. 無論 紋理 是否勾選了 sRGB (Color Texture) 選項,紋理格式都是不變的,例如都是 GL_COMPRESSED_RGB8_ETC2

b. framebuffer 格式  GL_RGBA8

 

3. linear 空間的下
的紋理格式和FrameBuffer格式

a. 紋理 勾選了 sRGB (Color Texture) 選項,紋理格式 GL_COMPRESSED_SRGB8_ETC2,而且紋理變暗了,它被作為一張sRGB紋理來看待,在傳入Shader的之前,會對texture進行pow(x,2.2),將輸入從sRGB空間轉換到線性空間,保證資料是線性的。硬體會對其作一次Pow2.2的gamma校正,將它轉化到線性空間中.

b. 紋理 沒有勾選了 sRGB (Color Texture) 選項,紋理格式 GL_COMPRESSED_RGB8_ETC2。而且紋理沒有變化,直接把紋理的資料當成是線性。硬體不會對它進行pow2.2的gamma校正操作

c. framebuffer的格式為GL_SRGB8_ALPHA8, framebuffer儲存資料是 經過了pow(x,1 / 2.2) 的gamma校正過的,硬體做的,就是從線性空間轉換到了sRGB空間——這當然是合理的,因為它要中和最後顯示器的gamma校正。也就是說,srgb的framebuffer儲存的就是 srgb格式的資料。

 

3. 透明混合

由於透明混合是一個線性的過程,因此在混合中作為Dst的那一方的framebuffer的資料就要是線性空間的了。
所以此時混合的操作事實上會先將framebuffer的內容從sRGB空間再次pow2.2轉換到線性空間,和src進行混合,再將混合後的結果pow0.45(pow(x,1 / 2.2))轉換回sRGB空間儲存到framebuffer中

在Linear Space 中的混合:

ret = (srcColor^2.2 * srcAlpha + dstColor^2.2 * (1 - srcAlpha) ) ^(1/2.2)

在gamma Space 中的混合:

ret = srcColor * srcAlpha + dstColor * (1 - srcAlpha)

 

4. 注意

這裡需要注意,Alpha通道是不會參與伽馬校正的,只是RGB。