Unity Linear Gamma色彩空間矯正測試


Gamma和Linear修正的問題相信網上已經有很多文章了。簡單來說顯示器的顏色輸出不是線性的,根據硬件參數和輸出顏色

信息擬合曲線是x^2.2,因此會使用一個x^0.45曲線將其擬合回線性。

 

因為0.5^0.45 = 0.73,0.5^2.2 = 0.217,我們可以通過一張0.5rgb的灰度圖放Unity中觀察變亮還是變暗

來判斷Unity在線性空間下做了哪些操作,以及參數配置是否正確。

 


 

這里進入URP渲染管線,並設置為Linear線性顏色空間進行測試:

測試1:一張圖片在ps里制作成(127,127,127)的純色,導入Unity。不勾選sRGB,輸出顏色較亮,勾選sRGB,輸出顏色正常

結論:最終顏色輸出時可能有gamma0.45處理。

 

測試2:frag里輸出顏色為0.5,該shader最終屏幕輸出時,輸出顏色較亮

結論:進一步確定輸出時有gamma0.45(pow(x,0.45))的處理。

 

測試3:增加一個UV偏移的shader參數值,在Gamma顏色空間和Linear顏色空間下切換查看,無區別

結論:顏色空間的修正處理類似濾鏡,而正常傳入Shader的字段數值不會做編解碼,不參與顯示相關的數值也不用做

糾正。

 

測試4:增加一個float類型的shader字段,直接輸出在frag里,並將參數值設為0.5。輸出顏色較亮,

而給參數加上[Gamma]前綴,輸出時顏色正常。

結論:因為最終輸出時屏幕會有一步gamma0.45處理,所以給常規參數追加一個gamma2.2處理,

這樣輸出就是原始顏色了(加上[Gamma]相當於pow(x,2.2))。

 

測試5(重要):Unity Linear顏色空間,一張Alpha0.5的純黑圖片,疊在白色背景上,但混合結果顏色並不是0.5的灰色。

嘗試加pow(2.2)手動修復,然后換成Alpha0.5的白色圖片,疊純黑背景上。發現僅是對Alpha值修改在混合處理上沒有用。

結論:首先明確一點Alpha通道不會進行sRGB矯正。但是Alpha值雖然沒問題,Unity的混合處理卻有問題。gamma0.45的修正是處理在

混合完成的結果上的,你並不知道混合結果的顏色是來自黑色疊白色,還是白色疊黑色,或是其他顏色相疊。

內建管線下可以創建Gamma RenderTexture,也就是sRGB為true的RT。但URP下似乎有些失效,所以這個問題博主自己目前還沒解決。

雖然單改Alpha值沒用,但我還是研究出了一個基於經驗的公式,通過讀取當前顏色和修改Alpha;做到了一部分還原:

float whiteAlpha = pow(color.a, 2.2);
float blackAlpha = 1.0 - pow((1-color.a), 2.2);
float lum = max(color.b, max(color.r, color.g));
color.a = lerp(blackAlpha, whiteAlpha, lum);
color.rgb *= color.a;

若要求不高又不想擴展管線,也可以試試。

 

最后總結下:

不用於圖像輸出的圖片,如噪波,就不需要勾選sRGB(不勾選sRGB也叫做保持Linear)。不用於圖像輸出的shader字段,如UV偏移值

就不用處理。用於圖像輸出的shader字段,需要加[Gamma]前綴或者手動調用Gamma22ToLinear。

同樣,用於顯示輸出的圖像如果中途要進行邏輯計算,需要調用LinearToGamma22轉回原始數值。

例如一些手游項目會合並多張貼圖到一張,這就導致了Linear和sRGB混在一張圖片內,這時候就需要代碼里手動去轉了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM