Unity Gamma校正轉為線性空間
相信大部分了解圖形學的人,都聽說過Gamma校正或者Gamma空間,線性空間這些詞。這裡不對Gamma Space形成的歷史原因做過多描述。Gamma和Linear空間的一些原理,文章也很多,包括Unity官網的描述,都可以看看。
顯示器顯示的Gamma空間的顏色變化規律,對應了下圖中的黃色曲線。當美術在Gamma空間中,RGB(255,255,255)的顏色單位上,增加了1的顏色亮度,最後輸出顯示的亮度,其實是低於1的。這個差距,在特別暗的地方更加明顯,也就容易讓場景因為太暗,而看不清細節。我們公司的美術也表示,線性空間的效果其實更加直觀,而Gamma空間的顏色有可能會越疊越深。所以為了更好的美術效果,尤其是讓貼圖的陰暗處有更多的細節,將Gamma Space轉換為Linear Space還是相當有必要的。
基本思路,一般來說就是通過pow(1/Gamma)將顏色強度提高。下圖中的藍色曲線是pow(1/2.2)的近似數,pow(0.45),這樣就可以抵消掉黃色曲線的變化,使顏色變化可以趨於線性。
三種函式的曲線
Infinite 3D Head Scan by Lee Perry-Smith,licensed under a Creative Commons Attribution 3.0 Unported License(available from www.ir-ltd.net)
雖然Unity 5.5開始,已經提供轉換工程為線性空間的功能,但是僅對OpenGLES 3.0及以上的裝置進行支援。詳細資料可以參考這篇Unity的Blog,可以看到,還有兩成左右的裝置是不具備這個條件的。所以如果專案組需要考慮低端機,尤其是考慮海外發行的話,就不能直接改變整個渲染空間。
因此替代的方法,是手動在Shader中,修改Colour Space。轉換空間用到的相關函式,Unity其實已經在Unity CG.cgnic中提供了,可以直接使用。
函式如下:
- inline float GammaToLinearSpaceExact (float value)
- {
- if (value <= 0.04045F)
- return value / 12.92F;
- else if (value < 1.0F)
- return pow((value + 0.055F)/1.055F, 2.4F);
- else
- return pow(value, 2.2F);
- }
- inline half3 GammaToLinearSpace (half3 sRGB)
- {
- // Approximate version from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
- return sRGB * (sRGB * (sRGB * 0.305306011h + 0.682171111h) + 0.012522878h);
- // Precise version, useful for debugging.
- //return half3(GammaToLinearSpaceExact(sRGB.r), GammaToLinearSpaceExact(sRGB.g), GammaToLinearSpaceExact(sRGB.b));
- }
- inline float LinearToGammaSpaceExact (float value)
- {
- if (value <= 0.0F)
- return 0.0F;
- else if (value <= 0.0031308F)
- return 12.92F * value;
- else if (value < 1.0F)
- return 1.055F * pow(value, 0.4166667F) - 0.055F;
- else
- return pow(value, 0.45454545F);
- }
- inline half3 LinearToGammaSpace (half3 linRGB)
- {
- linRGB = max(linRGB, half3(0.h, 0.h, 0.h));
- // An almost-perfect approximation from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
- return max(1.055h * pow(linRGB, 0.416666667h) - 0.055h, 0.h);
-
- // Exact version, useful for debugging.
- //return half3(LinearToGammaSpaceExact(linRGB.r), LinearToGammaSpaceExact(linRGB.g), LinearToGammaSpaceExact(linRGB.b))
- }
其中主要用到的是GammaToLinearSpace()和LinearToGammaSpace()。下面將說一下,到底怎麼用這兩個函式。
主要的思路是,把從貼圖中讀取進來的顏色,同時也是Gamma Space下的顏色,進行一次轉換,轉換到Linear Space。之後對這些顏色資料進行原本要進行的處理。處理結束後,在輸出的時候,進行一次逆轉換,將這些顏色資料,從Linear Space轉換回Gamma Space。
以下是我實際使用的一段程式碼:
- <blockquote>half4 color = UNITY_SAMPLE_TEX2D(_MainTex, i.uv);
補充一點,由於通道圖,一般來說,其實已經是線性的了,所以是不需要參與到這個轉換中的,直接用就好。但這段程式碼裡特別注意的一點是,最後轉換回Gamma Space的時候,我在Color上乘了一個Unity_ColorSpaceDouble。
最開始,我只進行了一個轉換回Gamma Space的方法,然後發現,場景不僅沒有變亮,反而變得更暗了。隨後查閱到一篇文章提到了,需要在最後轉回Gamma Space的時候,乘上一個值。
“與此相關的有,一個Unity提供的與色彩空間相關的值,Unity_ColorSpaceDouble。這個值在Gamma Color Space時為2,在Linear Color Space時為4.594(2的2.2次方)。對於這個值可以這樣來理解。一般在Gamma Color Space中將兩個Color值相乘後,為了避免顏色變得很暗,會在後面乘以2。”
也就是說,為了避免顏色變暗,應該擴大兩倍,但同時因為是線上性空間下,所以這個2要變成Unity_ColorSpaceDouble。
最後來看一下效果吧~
上圖為Gamma Space時的效果,下圖為做完一系列變換後的結果。可以看到,整體顏色變亮,尤其是暗部的亮度和細節都有明顯的提升。
可以看到特別暗的地方,在進行Gamma校正之後的變化也相對較大。所以這裡也需要注意一點,如果是專案已經進行了一段時期之後,想要進行Gamma校正,一定要同時修改光照等一系列引數,以避免一些地方的光照效果過曝。
作者:Luisa Z
來源:UWA
原地址:https://blog.uwa4d.com/archives/Usparkle_Gamma.html
相關文章
- 線性代數應該這樣學6:積空間,商空間,多項式
- 高等代數 第三章 線性空間
- Java 將PDF轉為線性PDFJava
- Unity射線(轉載存檔)Unity
- 2.5.4 為 SYSAUX 表空間指定資料檔案屬性UX
- win10如何校正時間 win10系統時間不同步怎麼校正Win10
- 三維空間的旋轉
- 2-色彩空間轉換
- C# 將PDF轉為線性化PDFC#
- Gamma調整GAM
- 空間反演對稱性 (Spatial Inversion Symmetry) 和非線性響應 (Non-linear Response)
- 區域性緊空間的基
- 空間曲線和曲面方程
- 檢查交換空間: 可用的交換空間為 0 MB, 所需的交換空間為 150 MB。 未通過
- MIT 線性代數 Linear Algebra 9: 向量空間的一些定義 -- 線性獨立,基,維度MIT
- 令人迷惑的GammaGAM
- Java物件為空時,不顯示該物件屬性,或者將null轉換為""Java物件Null
- 空間旋轉矩陣怎麼表示矩陣
- 43. 連續空間的只讀性
- <a>為空使用href屬性值填充
- ORACLE線上切換undo表空間Oracle
- 為什麼問題空間與解決方案空間如此重要? - Nikhil Gupta
- B站自研色彩空間轉換引擎
- 『OpenCV-Python』色彩空間及色彩轉換OpenCVPython
- 眾創空間聚焦辦公流動性,為年輕一代服務
- unix時間轉換為datetimedatetime轉換為unixtime
- 微信新功能上線:新增個性化板塊 獨有閱讀空間
- Android 校正系統時間的三種解決方案Android
- 16、表空間 建立表空間
- PostgreSQLoracle相容性-字串內嵌NULL字元(空字元)chr(0)轉換為chr(32)SQLOracle字串Null字元
- 時間戳轉化為時間格式時間戳
- Oracle 10g大檔案表空間(轉)Oracle 10g
- MySQL空間最佳化(空間清理)MySql
- 線性時間構造最大堆
- 為什麼用元空間替代永久代?
- 13.0.高等數學3-空間曲線
- 跟我一起學《深度學習》第二章 線性代數(2.4 線性相關和生成子空間 )深度學習
- 自動控制原理(考研)理論篇--第七章(線性離散系統的分析與校正)