OpenGL光照計算中法線矩陣原理及推到過程

問題起源

在計算漫反射關照時,須要用到法線,經過法線和光線的點乘值,計算漫反射的產生的光線強度,因此須要從頂點着色器中將法線數據傳遞到片源着色器中,可是片源着色器中的頂點座標是通過了模型矩陣變化過的世界座標.因此兩者極可能已經不匹配了,固然模型矩陣是單位矩陣的特殊狀況下,就沒有影響.blog

對法線進行mv變換

所以,須要對法線也應用mv矩陣變換.這樣,模型的在旋轉和縮放後,法線才能也與之匹配,以下圖這樣:
image原理

去掉對法線的偏移效果

但有個問題,就是偏移,若是法線跟着一塊兒偏移,方向就會出問題了,加入模型矩陣沿x方向偏移一點,法線的x也相應的增長一點,就會出現下面這樣的狀況:
image
這種狀況能夠經過將法線的齊次座標設置爲0,來解決,由於偏移的原理就是矩陣最後一列的值乘以其次座標產生的影響:
image反射

不等比縮放

大部分狀況下,上面的處理就能夠獲得想要的效果了,可是,若是mv矩陣中存在不等比縮放,那麼會出現法線與原來的面不垂直的問題,雖然在不少狀況下這個效果可能不會太明顯,由於法線誤差一點點,關照計算並不會有特別明顯的區別:
image
可是當不等比縮放的不一樣軸之間的差距很大時,這個效果就會更明顯了.像下面這樣:
image
這個時候計算出來的光照就會和預期的有很明顯的區別,給人很怪異的感受了.im

法線矩陣

這個時候,須要使用發現矩陣,其實就是模型矩陣逆矩陣的轉置矩陣,用上效果立馬就對了.
image數據

模型矩陣逆矩陣的轉置矩陣做用原理

用法很簡單,原理仍是須要點時間來理解的.
首先咱們的目標是法線最終須要與頂點的切線垂直.
定義:原法線爲n,變換後法線爲N,原來頂點處切線爲t,變換後切線爲T,模型矩陣爲M,要計算的結果法線矩陣爲X.
.表示點乘,表示矩陣乘以向量(也能夠省略),或者向量間叉乘,`表明:
n . t = 0; //法線與切線垂直,因此點乘爲0
N . T = 0; //最終結果亦垂直
N = X * n
T = M * t
將第三,四個方程帶入第二個方程:
(X * n) . (M * t) = 0
點乘變換成叉乘
(X * n) . (M * t) => (X * n)T * (M * t) => 省略* => (Xn)T * Mt
=> nTXT * Mt
因爲n . t = 0
XTM = I
n . t = N . T = 0
XTM = I => X = (M-1)Timg

相關文章
相關標籤/搜索