文章目錄
- Unity 中的 gamma、linear 作業流
- Linear 作業流
- References
我們一般說的 gamma correction 簡稱 gamma,而 gamme correction 就是對 pow(inputVal, 1.0 / 2.2) 也就是提亮顏色的處理,而 gamme correction 的逆運算可以簡稱:de-gamma,就是 pow(inputVal, 2.2) 也就是壓低亮度的處理
因為我們人眼在看到真實世界中的亮度值時,在眼球編碼生物神經電信號給大腦中的灰度感知并非線性的(人眼會將 pow(inputVal, 2.2) 處理,會將原來的線性顏色表現出來的亮度整體偏暗,這種視覺效果感覺很差
所以我們為了提高視覺效果更好,才會在顏色輸出給人眼看到之前,先將其提亮顏色,也就是A=pow(inputVal, 1.0/2.2),這樣將提亮過的結果,給到人眼時呈現的是 pow(A, 2.2) 顏色亮度,但是剛剛說過,給人眼看前提亮,人眼編碼在大腦壓低亮度,這一升一降,剛剛好變成線性的,所以這是在人腦中的灰度信號是線性的,那么視覺上自然就會舒服很多,但是實際上真正的物理亮度是被提亮過的
如果有些設備,如:CRT,也是會降低亮度的輸出,那么就在 CRT 輸出前 2 次 gamme 校正,這樣,CRT 降低1次,人眼再降低1次,剛剛好看起來就像是在 線性變化的感覺(注意這時人眼看到的輸出結果都是被提亮過的,不提亮就會偏暗,人眼對灰度的感知編碼不是線性的)
下面用 GGB 來顯示對應的操作:
- GC? Gamma Correct(因為 CRT、人眼 設備等,會降低亮度的編碼方式,所以需要 gamma 校正)
- L? Linear(如果我們傳入人眼的是 GC 過得,腦子呈現的灰度將會是 Linear 的變化)
- DGC? De-Gamma Correct (人眼將資料 Linear 后的資料壓低亮度就變成這條曲線的亮度)

所以如果你在 shader,或是其他一些代碼中可能會看到 pow(val, 0.4545) 的其實就是 pow(val, 1.0 / 2.2) 的一個 gamma correct 操作
因為 1.1/2.2 == 0.4545454545 無盡小數部分
Unity 中的 gamma、linear 作業流
在 Unity 中,涉及到 gamma correct 等顏色空間的有:
- Edit/Project Settings…/Player/Other Settings/Color Space: Gamma 或是 Linear
- 每個紋理資源只要是顏色型別的紋理(不是 AO, Normal, Height 貼圖),那么 sRGB 的勾選需要在對應的 Color Space 下選擇是否勾選:
- 在 Color Space 為 Gamma 時,勾上(Unity 默認情況下時會勾上的)
- 在 Color Space 為 Linear 時,不要勾上
- 因為 Unity 的紋理的 sRGB 屬性意思是:是否對已有顏色資料進行 Gamma Correct 處理,也就是上面 GGB 函式中對應的
GC函式處理,GC(x) = pow(x, 1.0 / 2.2),這個紋理里面的資料,給到外部訪問、使用時,是否需要先提亮一下的 gamma correct 處理 - 那么線性空間中,我們需要確保我們輸入給 shader 計算的都是 linear 值才行,這樣運算結果才能正確,最終輸出給螢屏,而輸出給螢屏設備有分情況:
- 我們螢屏設備(如:LED)對輸入資料可以線性的控制灰度輸出,那么我們只要確保設備是否會硬體層處理了 gamma correct:
- 如果螢屏硬體沒有 gamma correct,那么我們給這種設備輸出資料前,收到給 FB(FrameBuffer),后處理一遍對每個像素 gamme correct 一下
return half4(pow(tex2D(_MainTex, uv).rgb, 1.0/2.2), alpha); - 如果有螢屏硬體有集成處理 gamma correct,那么我們就不要再處理任何的 gamma correct 了
- 如果螢屏硬體沒有 gamma correct,那么我們給這種設備輸出資料前,收到給 FB(FrameBuffer),后處理一遍對每個像素 gamme correct 一下
- 如果我們的螢屏設備(如:CRT)對輸入資料不可以線性的控制灰度輸出,那么我們確保設備是否處理了 gamma,沒有的話,同上處理
- 我們螢屏設備(如:LED)對輸入資料可以線性的控制灰度輸出,那么我們只要確保設備是否會硬體層處理了 gamma correct:
Unity 中的 Linear 作業流簡單的總結:
- Color Space : Linear
- 只要和直接表述灰度值有關的紋理資訊,如:albedo,那么都要確保 sRGB 不要勾上
- 其他資料紋理(AO, NORMAL, HEIGHT )貼圖,也不需要 sRGB,一般你選擇了類似型別后,也不會有 sRGB 勾選項的顯示,即:不需要的意思
- 然后我們在 shader 中確保有在 last frame buffer 的寫入后,給設備資料前,要 gamma 一次就可以了(目前發現,如果在 Color Space : Linear 下,UNITY 會在最后一個 dc 的后處理 gamma 提亮處理)
Linear 作業流
下面流程圖是暫時的編輯結果,還有 gamma 作業流的,后續再增加處理吧

References
- Color space - unity 官方的檔案 - 建議先看這個 大智的講解(相信里面的部分理解也是看過 韓世鱗 老師的視頻)
- Gamma校正與線性作業流入門講解 - 韓世鱗 老師的講解,太牛逼了
- Gamma校正 - 結合大部分 DCC 的涉及 gamma 校正的處理,很不錯
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/397493.html
標籤:其他
上一篇:用C++寫的猜數字游戲
下一篇:PY劃水第2天
