一個unity3d lightmap問題


  上周美術同學在使用unity3d制作lightmap的過程中,發現部分被lightmap影響的模型在移動端上效果與pc端不一致。當時我大概看了下,分析后,得到一個結論是“在移動端上lightmap的hdr格式轉換到ldr格式后,着色時沒有進行tonemap的還原”。因此效果就是曝光度>1的部分,最多只能顯示出原本模型diffuse貼圖的色調,而不是達到曝光的色調。所以當時我給出的解決辦法就是將hdr->ldr轉換時的壓縮比列得到,最后在shader采樣出ldr光照貼圖后使用這個比例值還原hdr的效果。當然具體怎么做,還必須參考unity3d內部的要求。

  到了本周,得知進展不大。於是自己深入了解了一下unity3d的shader。

  unity3d的shader其實是廣義上的,包含了部分render state的描述,具體可以使用三種描述方式:

  <1> surface shader:它是untiy3d的一種shader描述腳本,其作用就是通過untiy3d定義好的描述語法,將引擎內部已經實現好了的着色代碼組合起來。從而簡化了大量重復代碼的書寫,以及屏蔽一些具體的3d圖形實現細節。我們可以理解為這是一種傻瓜式的shader。

  <2> vertex and fragment shaders:普通的着色語言,hlsl,cg,glsl等。

  <3> fixed function shader:一種描述腳本,用來操作固定管線的state。

  如果要解決上面這個問題,第一步我們需要得到hdr->ldr的比例。雖說unity3d lightmap烘焙使用的是beast,但是具體這個比例是多少,存放在哪里,這些細節無法查到。似乎引擎封裝了它,但沒有暴露出來。好在它提供了DecodeLightmap這個函數來還原,這個函數內部在移動端和gles下將亮度*2,在pc端下將亮度*8*light_alpha通道。這樣看來在pc端下,ldr的還原程度更高,有8的亮度值,而移動端只有2。第二步就是將這個函數計算的還原值作為lightmap的亮度值*diffuse貼圖就可以了。

  由於在移動端只有2倍,因此當烘焙時燈光強度大於2時,還是有問題。這時可以通過一些簡單的tone map算法對light map的值進行一些調整,使其盡可能達到美術想要的效果。最簡單的方式就是將lightmap的灰度調低,然后在shader中對lightmap的值乘上更大的比例。


免責聲明!

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



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