使用世界变换的逆转置矩阵对法线进行变换

法向量变换细节记录

最近在做法向量变换的时候,踩了两个坑,记录一下相关的知识点

法向量做变换,最后一位是补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

posted @ 2024-06-30 10:09  CuriosityWang  阅读(75)  评论(0编辑  收藏  举报