GLSL教程 (九)其他說明

2021-08-21 10:21:38 字數 1537 閱讀 3286

法線矩陣

在很多頂點shader中都用到了gl_normalmatrix。這裡將介紹這個矩陣是什麼,以及它的作用。

大部分計算是在檢視空間內完成的,主要原因是光照的運算要放在這個空間內,否則一些依賴觀察點座標的效果,比如鏡面反射光就很難實現。

所以我們需要將法線變換到檢視空間。變換乙個頂點到檢視空間的方法如下:

vertexeyespace = gl_modelviewmatrix * gl_vertex;

在上圖中我們可以看到乙個三角面以及它的法線和切線。下圖顯示了如果模型檢視矩陣包含非一致縮放(non-uniform scale)的話會發生什麼。

注意,如果縮放是一致的(uniform),那麼法線方向保持不變,變的只是長度,而且可以通過歸一化修正這個影響。

在上圖中,模型檢視矩陣應用到所有頂點以及法線上,最後的結果明顯錯誤:法線不再與三角面垂直了。

現在我們知道模型檢視矩陣在某些情況下,不能用來變換法線向量。下面的問題就是:那麼該使用哪個矩陣?

考慮乙個3×3矩陣g,讓我們看看要正確變換法線,這個矩陣該是什麼樣子。

我們知道,變換前切線和法線是垂直的,即t•n = 0,在變換後切線和法線同樣應該保持垂直,即t』•n』 = 0。現在假設g是正確變換法線的矩陣,同時模型檢視矩陣的左上3×3子矩陣m可以正確變換切線t(t是乙個向量,所以w成分為0)。因為t可以通過兩個頂點的差來計算,所以變換頂點的矩陣同樣可以用來變換t。由此可以得到如下等式:

向量的點乘相當於向量的內積,所以有:

我們知道相乘的轉置等於分別轉置再交換順序相乘:

已知n和t點乘結果為0,所以如果下式成立就可以滿足等式為0:

即有:可見變換法線的正確矩陣是m的逆的轉置。opengl計算出的這個矩陣就儲存在gl_normalmatrix裡。

在本節開始討論過,某些情況下使用模型檢視矩陣也可以。當模型檢視矩陣的左上3×3子矩陣m正交時,可以得到:

乙個正交矩陣的所有行/列都為單位向量,並且互相正交。當兩個向量乘上正交矩陣時,它們之間的夾角在變換前後不變。由於這種保角變換的關係,所以法線和切線依然儲存垂直。此外,向量的長度也保持不變。

m在什麼時候能確定為正交的呢?當我們把幾何變換限制為旋轉和平移時(在opengl應用程式中只使用glrotate和gltranslate,而不使用glscale),就可以保證m正交。注意:glulookat同樣建立正交矩陣。

關於法線歸一化

當乙個法線到達頂點shader後,我們一般會將它歸一化:

normal = normalize(gl_normalmatrix * gl_normal);

注意,如果頂點法線沒有單位化,那麼得到的插值法線的方向也將是錯誤的。所以,即使乙個頂點沒有在頂點shader用到,也可能要對它在頂點shader中進行歸一化。

有一種情況,在片斷shader中可以避免歸一化操作,那就是每個頂點法線方向相同,而且頂點法線是經過歸一化的。此時頂點法線插值得到的結果都相同。

以方向光為例,每個片斷都需要考慮光線方向,如果光線向量已經在之前歸一化了,在片斷shader中就可以避免歸一化這一步。

GLSL教程 (九)其他說明

法線矩陣 在很多頂點shader中都用到了gl normalmatrix。這裡將介紹這個矩陣是什麼,以及它的作用。大部分計算是在檢視空間內完成的,主要原因是光照的運算要放在這個空間內,否則一些依賴觀察點座標的效果,比如鏡面反射光就很難實現。所以我們需要將法線變換到檢視空間。變換乙個頂點到檢視空間的方...

GLSL教程 (九)其他說明

法線矩陣 在很多頂點shader中都用到了gl normalmatrix。這裡將介紹這個矩陣是什麼,以及它的作用。大部分計算是在檢視空間內完成的,主要原因是光照的運算要放在這個空間內,否則一些依賴觀察點座標的效果,比如鏡面反射光就很難實現。所以我們需要將法線變換到檢視空間。變換乙個頂點到檢視空間的方...

GLSL教程 (九)其他說明

from 法線矩陣 在很多頂點shader中都用到了gl normalmatrix。這裡將介紹這個矩陣是什麼,以及它的作用。大部分計算是在檢視空間內完成的,主要原因是光照的運算要放在這個空間內,否則一些依賴觀察點座標的效果,比如鏡面反射光就很難實現。所以我們需要將法線變換到檢視空間。變換乙個頂點到檢...