法線貼圖原理


法線貼圖原理

  如果法線處於世界坐標中的(world space),那稱為world space normal。如果是處於物體本身局部坐標中的,那稱為object space normal。

  很容易想象,world space normal一旦從貼圖里解壓出來后,就可以直接用了,效率很高。但是有個缺點,這個world space normal 是固定了,如果物體沒有保持原來的方向和位置,那原來生成的normal map就作廢了

  因此又有人保存了object space normal。它從貼圖里解壓,還需要乘以model-view矩陣轉換到世界坐標,或者轉換到其他坐標取決於計算過程及需求。object space normal生成的貼圖,物體可以被旋轉和位移.基本讓人滿意。但仍有一個缺點。就是一張貼圖只能對應特定的一個模型,模型不能有變形(deform)

  變形時,頂點關系改變了,即面的形狀,方向改變了。如果面上存在一個固定的坐標系,那當物體變形、移動、旋轉時,這個坐標系必定跟着面一起運動,那么在這個坐標系里的某個點或向量,不需要變動。當整個面發生變化時,我們只需要計算面上的坐標系到世界坐標系的轉換矩陣,那么定義在這個面上的點或坐標(固定的),乘以這個矩陣即可得到在世界中的坐標。這個坐標系術語里稱為tangent space。

  按照新方法每個面都有一個局部坐標系,當低模變形時,即三角面變化時,它的tangent space也會跟着變化,保存在貼圖里的法線乘以低模這個面的tangent space到外部坐標系的轉換矩陣即可得到外部坐標。

  CG中頂點已經自帶tangent、normal信息,TxN即可得到B。T、B、N即可構造出切換空間。

  現在我們可以分析為什么tangent space法線貼圖是偏藍色了.因為這個面渲染時計算機認為這個面的"彎曲"程度很小,即面上各個點插值得來的法線相互間偏差很小.基本跟整個面的垂直方向不會差太多.因此在tangent space里,這些法線都跟z軸偏差較小.而z軸是被保存在貼圖里的b字節處(藍色通道)里.所以貼圖顯示出來的顏色就偏藍了.

  假設在低模上的某個面我們計算出了TBN矩陣,並取出了面上某點的對應在法線貼圖里法線值.現在需要計算光照.我們可以把光向量轉換到tangent space里做計算.也可以把得到的法向量轉換到world space與光向量進行計算.結果是一樣的.實際考量,你會發現后一種方法不好.因為對於面上的每個點,都要計算一次normal到world space的轉換.而前一種方法,對一個面上的所有點,只要計算一次光向量到tangent space的計算.然后再考慮到vertex shader與fragment shader的流程,你會發現剛好我們可以在vertex shader計算光線到tangent space的轉換,在fragment sader取出法線值與前面得到的tangent space里的光線方向做計算即可.這里提醒一下,一般verteix shader中我們得到的光線方向是基於world space的,而法線貼圖保存的是高模的object space內的方向然后再轉換到tangent space,所以在vertex shader中,我們必須先把光線先轉換到object space,再轉換到tangent space.這樣才能保證最終計算時,光線與法線是基於同一個坐標系的.這也是你在很多normal map的shader里,看到類似ToOjectSpaceDir(lightDir)之類函數的原因,正是要把光轉換到object space.

參考:http://blog.csdn.net/damenhanter/article/details/22481563


免責聲明!

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



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