轉載自:http://blog.csdn.net/bugrunner/article/details/7285356
法向量只有方向沒有大小,平移變換不會改變法向量,旋轉變換M^-1^T逆的轉置還是本身,均勻縮放變換也不會改變法向量,所以一般游戲中應用的變換可以直接作用于法向量變換,如果存在不均等的縮放變換,那么對法向量進行MV變換會得到不正確的結果,這個時候就要對法向量進行M^-1^T逆變換,推導見如下,或者在變換后重新計算法向量。
關于三維空間法線變換的問題,之前就有看到過,但是一直也木有注意,普通的三維空間中的法線變換還是直接使用模型的變換矩陣來進行。但是,近來又看到了一些這方面相關的東西,因而總結一下。
已經知道不能直接用模型變換矩陣來變換Normal,比如使用某含有非一致性縮放(在x,y,z方向上進行不程度的拉伸)的變換矩陣來變換一球體,則可能得到如下列圖示的結果:
左圖為原始球體及其表面上的法向分布(2D投影后);中間為直接使用變換矩陣操作后的法向分布,但注意其明顯與表面不垂直;右圖為正確變換后的法向分布。為什么直接變換不正確呢?網上有多種說明版本,但是對比了一下感覺還是PBRT上的解釋比較好一些。這里假設某一點處的法向量為n,切向量為t,由兩者在曲面上的垂直關系可知:
如果對于模型進行空間變換的矩陣為M,變換后在該點得到的新的切向量為,那么可得
(這里假設切向量并不是由變換矩陣計算得到的,而是直接通過對模型表面進行幾何分析計算得到的);變換后在該點得到新的法向量為
,若是得到的正確法向量,則其必定仍然與切向量垂直。假設正確變換得到的法向量是在變換矩陣S下進行的,那么有
,由法、切的垂直關系得:
在上式的最后階段中可以看出,如果要滿足成立條件則有,直接變換即可得
,所以也就有:
這里就得到了通常我們所說的采用逆的轉置矩陣來代替原始變換矩陣來對法向量進行操作。上述推導中使用的一個依據是切向量與法向量之間的垂直關系,其實這是建立在另外一個基礎上,那就是:切向量的計算一般是直接使用頂點與UV來進行,這樣的話它就是直接與頂點相關,因而只要直接使用變換矩陣得到的頂點正確那么在此基礎上計算而來的切向量也就正確,但是法向量卻不是直接通過頂點計算、而是通過變換得到的(當然,如果Normal 也在網格頂點變換之后直接計算,而不是對原始的法向量用變換矩陣作空間變換的話就不會存在這一問題了)
另外,在實際操作中對于變換矩陣(一般為4x4的)并不一定可逆(比如一個由3D到2D的投影矩陣),因而上述S就沒法計算,這種情況下更安全的一種方法是只使用原始4x4變換矩陣的左上角3x3矩陣,即不考慮平移部分,其實這也理所當然,平移操作本就不影響法向量。這一部分在Realtime Rendering中也有稍詳細的說明。
當然,使用逆的轉置來進行Normal變換只是正確方法的一種,不過也有其它的方法,比如從一個變換矩陣中只抽取出Rotation的部分來施加到Normal上,這樣就免去了Translation和Scale的影響。矩陣的R, T, S分解也有很多經典的方法,可以參考一個這個帖子:http://www.gamedev.net/topic/441695-transform-matrix-decomposition/(雖然這種方法的效率與復雜度需要另外討論,但畢竟也是一個途徑)
不過一般情況下,我們對于場景中三維模型的變換基本上都是進行三向一致的縮放操作,這樣的話M就是一個正交的矩陣,如此一來就有S等于M,因而直接使用M對法向量作變換也不會有什么問題出現(或者有差別也被忽略了^_*)。不過任意的縮放變換是建模工具的一個基本需求,因而在做工具時需要重視這一問題。
新聞熱點
疑難解答