日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Unity Gamma校正转为线性空间

發(fā)布時間:2024/8/26 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Unity Gamma校正转为线性空间 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


相信大部分了解圖形學(xué)的人,都聽說過Gamma校正或者Gamma空間,線性空間這些詞。這里不對Gamma Space形成的歷史原因做過多描述。Gamma和Linear空間的一些原理,文章也很多,包括Unity官網(wǎng)的描述,都可以看看。

顯示器顯示的Gamma空間的顏色變化規(guī)律,對應(yīng)了下圖中的黃色曲線。當(dāng)美術(shù)在Gamma空間中,RGB(255,255,255)的顏色單位上,增加了1的顏色亮度,最后輸出顯示的亮度,其實是低于1的。這個差距,在特別暗的地方更加明顯,也就容易讓場景因為太暗,而看不清細(xì)節(jié)。我們公司的美術(shù)也表示,線性空間的效果其實更加直觀,而Gamma空間的顏色有可能會越疊越深。所以為了更好的美術(shù)效果,尤其是讓貼圖的陰暗處有更多的細(xì)節(jié),將Gamma Space轉(zhuǎn)換為Linear Space還是相當(dāng)有必要的。

基本思路,一般來說就是通過pow(1/Gamma)將顏色強度提高。下圖中的藍色曲線是pow(1/2.2)的近似數(shù),pow(0.45),這樣就可以抵消掉黃色曲線的變化,使顏色變化可以趨于線性。
?

三種函數(shù)的曲線

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開始,已經(jīng)提供轉(zhuǎn)換工程為線性空間的功能,但是僅對OpenGLES 3.0及以上的設(shè)備進行支持。詳細(xì)數(shù)據(jù)可以參考這篇Unity的Blog,可以看到,還有兩成左右的設(shè)備是不具備這個條件的。所以如果項目組需要考慮低端機,尤其是考慮海外發(fā)行的話,就不能直接改變整個渲染空間。

因此替代的方法,是手動在Shader中,修改Colour Space。轉(zhuǎn)換空間用到的相關(guān)函數(shù),Unity其實已經(jīng)在Unity CG.cgnic中提供了,可以直接使用。

函數(shù)如下:
?

  • 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));
  • }
  • 復(fù)制代碼
  • 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))
  • }
  • 復(fù)制代碼


    其中主要用到的是GammaToLinearSpace()和LinearToGammaSpace()。下面將說一下,到底怎么用這兩個函數(shù)。

    主要的思路是,手機靚號買號把從貼圖中讀取進來的顏色,同時也是Gamma Space下的顏色,進行一次轉(zhuǎn)換,轉(zhuǎn)換到Linear Space。之后對這些顏色數(shù)據(jù)進行原本要進行的處理。處理結(jié)束后,在輸出的時候,進行一次逆轉(zhuǎn)換,將這些顏色數(shù)據(jù),從Linear Space轉(zhuǎn)換回Gamma Space。

    以下是我實際使用的一段代碼:

  • <blockquote>half4 color = UNITY_SAMPLE_TEX2D(_MainTex, i.uv);
  • 復(fù)制代碼


    補充一點,由于通道圖,一般來說,其實已經(jīng)是線性的了,所以是不需要參與到這個轉(zhuǎn)換中的,直接用就好。但這段代碼里特別注意的一點是,最后轉(zhuǎn)換回Gamma Space的時候,我在Color上乘了一個Unity_ColorSpaceDouble。

    最開始,我只進行了一個轉(zhuǎn)換回Gamma Space的方法,然后發(fā)現(xiàn),場景不僅沒有變亮,反而變得更暗了。隨后查閱到一篇文章提到了,需要在最后轉(zhuǎn)回Gamma Space的時候,乘上一個值。

    “與此相關(guān)的有,一個Unity提供的與色彩空間相關(guān)的值,Unity_ColorSpaceDouble。這個值在Gamma Color Space時為2,在Linear Color Space時為4.594(2的2.2次方)。對于這個值可以這樣來理解。一般在Gamma Color Space中將兩個Color值相乘后,為了避免顏色變得很暗,會在后面乘以2?!?/span>

    也就是說,為了避免顏色變暗,應(yīng)該擴大兩倍,但同時因為是在線性空間下,所以這個2要變成Unity_ColorSpaceDouble。

    最后來看一下效果吧~
    ?


    上圖為Gamma Space時的效果,下圖為做完一系列變換后的結(jié)果??梢钥吹?#xff0c;整體顏色變亮,尤其是暗部的亮度和細(xì)節(jié)都有明顯的提升。
    ?


    可以看到特別暗的地方,在進行Gamma校正之后的變化也相對較大。所以這里也需要注意一點,如果是項目已經(jīng)進行了一段時期之后,想要進行Gamma校正,一定要同時修改光照等一系列參數(shù),以避免一些地方的光照效果過曝。

    總結(jié)

    以上是生活随笔為你收集整理的Unity Gamma校正转为线性空间的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。