天天看點

法線貼圖

模型的光照效果是通過存儲在頂點中的法線方向和光照角度計算得到的,當頂點數不多的時候,三角形上的法線方向是通過硬體插值得到的,由于硬體插值得到的是一個平滑的數值,這就造成了表面失去凹凸起伏的細節。法線貼圖就是為了彌補這個而出現的,是以使用了法線貼圖後,模型的法線方向可以細化到像素級别,而不是頂點級别。關于法線貼圖的細節可以看這篇文章,這裡面已經講得很清楚了。下面主要說一下在使用法線貼圖時,如果模型的光照效果不正确,可能的一些檢查點。

如果使用的是 Unity 内置的 Bump 類 Shader,那麼第一個可以排除的就是 Shader 代碼本身的問題。首先要檢查的是模型本身的法線和切線是否正确,很多非技術類人員會很自然的認為有了法線貼圖模型就不需要模型法線了,模型空間中的法線貼圖确實是這樣的,但是絕大多數的法線貼圖都是切線空間中的,模型本身的法線和切線決定了切線空間,是以這一點是很重要的。至于如何檢查,可以直接在 Maya 或者 3DMax 中打開模型,都會有指令來顯示出法線,或者可以直接在 Unity 裡檢查(看這裡的方法)。然後要檢查的就是法線貼圖了,要明白的是法線貼圖中每一個顔色通道表示的是什麼,紅、綠、藍分别代表切線空間中的切線、副切線、法線,對于左手坐标系和右手坐标系來說,副切線的方向是相反的(看下圖),這也就是為什麼有的時候需要把法線紋理的綠色通道反轉一下的原因了。

法線貼圖

如果沒有使用 Unity 内置的 Shader,而是自己實作,除了檢查上述問題外,還需要仔細的檢查下代碼。其實使用法線貼圖計算光照和使用模型法線計算光照的計算方法都是一樣的,隻是一個切線空間的差別,關于切線空間還是看上面提到的那篇文章。在計算的時候要明确知道在哪個空間計算的光照,因為有的時候時候直接把 ViewDir、LightDir 轉換到切線空間更合适,而有的時候把切線空間的法線轉換到 WorldSpace 更合适(不管是自己寫 VF Shader 還是 Unity 的 Surface Shader 都是如此)。

最後說明下 Shader 中計算付切線的代碼:

float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w;
           

剛看到最後乘以的 v.tangent.w 會表示不解,不明白其意思。其實這就是上文中說的左右手坐标系的差別了。如果不想反轉綠色通道,那麼可以直接修改

v.tangent.w

,當然為了統一和一緻性是不建議這麼做,隻是作為一個小技巧。

goto https://chengkehan.github.io/NormalMap.html

https://chengkehan.github.io