使用世界變換的逆轉置矩陣對法線進行變換

CuriosityWang發表於2024-06-30

法向量變換細節記錄

最近在做法向量變換的時候,踩了兩個坑,記錄一下相關的知識點

法向量做變換,最後一位是補0

我們知道,頂點在做變換的時候最後一位是 1.0,法線最後一位是補0.0

vec3 normCurrent = (getMatrixWorld() * vec4(normCurrent, 0.0)).xyz; // 法線變換
vec3 pointCurrent = (getMatrixWorld() * vec4(pointCurrent, 1.0)).xyz; // 頂點變換

這主要是因為,將法線的最後一位設為0,可以消除位移對法線的影響;

首先,法向量只是一個方向向量,不能表達空間中的特定位置。同時,法向量沒有齊次座標(頂點位置中的w分量)。這意味著,位移不應該影響到法向量。因此,如果我們打算把法向量乘以一個模型矩陣,我們就要從矩陣中移除位移部分,只選用模型矩陣左上角3×3的矩陣(注意,我們也可以把法向量的w分量設定為0,再乘以4×4矩陣;這同樣可以移除位移)。對於法向量,我們只希望對它實施縮放和旋轉變換。

aed9dced685f2594a39fe30f3b4528ba

使用世界變換的逆轉置矩陣對法線進行變換

當我擁有物體座標系下的法線,我想將其變換到世界座標系,只需要乘一下model矩陣就可以了嗎,答案是否定的,我們可以看一下這張圖,當模型發生了不等比縮放的時候:

CamScanner 06-27-2024 16.22_02

此時對法向量應用相同的變換,得到的法向量不再垂直於表面。(注意:等比縮放不會破壞法線,因為法線的方向沒被改變,僅僅改變了法線的長度,而這很容易透過標準化來修復),法向量就不會再垂直於對應的表面了,這樣光照就會被破壞。

那應該怎麼對法向量進行變換呢,請看下面的推導,引用知乎上的回答:

image-20240627164312153

refer

  • https://learnopengl-cn.github.io/02 Lighting/02 Basic Lighting/
  • https://www.zhihu.com/question/27739027

相關文章