成都网站建设空间,ui设计在哪个网站可以接做,百度推广代理查询,网页制作基础知识答案背景
在冯氏光照模型中#xff0c;其中的漫反射项需要我们对法向量和光线做点乘计算。
从顶点着色器中读入的法向量数据处于模型空间#xff0c;我们需要将法向量转换到世界空间#xff0c;然后在世界空间中让法向量和光线做运算。这里便有一个问题#xff0c;如何将法线…背景
在冯氏光照模型中其中的漫反射项需要我们对法向量和光线做点乘计算。
从顶点着色器中读入的法向量数据处于模型空间我们需要将法向量转换到世界空间然后在世界空间中让法向量和光线做运算。这里便有一个问题如何将法线从当前的模型空间变换到世界空间
首先法向量只是一个方向向量不能表达空间中的特定位置。同时法向量没有齐次坐标顶点位置中的w分量。这意味着位移不应该影响到法向量。因此如果我们打算把法向量乘以一个模型矩阵我们就要从矩阵中移除位移部分只选用模型矩阵左上角3×3的矩阵注意我们也可以把法向量的w分量设置为0再乘以4×4矩阵这同样可以移除位移。对于法向量我们只希望对它实施缩放和旋转变换。
其次如果模型矩阵执行了不等比缩放顶点的改变会导致法向量不再垂直于表面了。因此我们不能用这样的模型矩阵来变换法向量。下面的图展示了应用了不等比缩放的模型矩阵对法向量的影响 当我们应用一个不等比缩放时注意等比缩放不会破坏法线因为法线的方向没被改变仅仅改变了法线的长度而这很容易通过标准化来修复法向量就不会再垂直于对应的表面了这样光照就会被破坏。
修复这个行为的诀窍是使用一个为法向量专门定制的模型矩阵。这个矩阵称之为法线矩阵(Normal Matrix)它使用了一些线性代数的操作来移除对法向量错误缩放的影响。
推导过程
为了将一个顶点从模型空间转换到世界空间我们可以乘上一个模型矩阵model包含物体的移动、旋转、缩放信息。在shader中的代码如下
FragPos vec3(model * vec4(aPos, 1.0));对于一个向量正如上面的图展示的一样我们不能简单乘上model矩阵。如果乘上model矩阵向量就不再和原来的表面切线垂直了。
我们可以定义表面切线为 T P 2 − P 1 T P_2 - P1 TP2−P1其中 P 1 , P 2 P_1,P_2 P1,P2都是表面上的顶点。当表面前线乘上model矩阵时我们有 m o d e l ∗ T m o d e l ∗ P 2 − m o d e l ∗ P 1 T ′ P 2 ′ − P 1 ′ model * T model * P_2 - model * P_1 \\ T P_2 - P_1 model∗Tmodel∗P2−model∗P1T′P2′−P1′ 变换后的表面切线 T ′ T T′仍然可以表示成表面上顶点的差因此乘上model矩阵之后表面切线不会被破坏。
对于表面上的法线 N N N我们无法从表面上找到两个顶点来表示但是我们知道表面法线与切线互相垂直即 N ⋅ T 0 N \cdot T 0 N⋅T0 我们假设矩阵 G G G就是可以将法线从模型空间转换到世界空间的正确矩阵并用 M M M来表示模型矩阵model于是有下式 N ′ ⋅ T ′ ( G N ) ⋅ ( M T ) 0 N \cdot T (GN)\cdot(MT) 0 N′⋅T′(GN)⋅(MT)0 转化成矩阵表示的形式 ( G N ) ⋅ ( M T ) ( G N ) T ∗ ( M T ) N T G T M T 0 (GN)\cdot(MT) (GN)^T*(MT) N^TG^TMT 0 (GN)⋅(MT)(GN)T∗(MT)NTGTMT0 我们知道 N ⋅ T N T T 0 N\cdot T N^TT 0 N⋅TNTT0所以如果 G T M a I G^TM aI GTMaI a a a是任意非零常数我们便有 N ′ ⋅ T ′ N T G T M T N T a I T a N T T 0 N\cdot T N^TG^TMT N^TaIT aN^TT 0 N′⋅T′NTGTMTNTaITaNTT0 由于我们不想改变法向量的模长因此令 a 1 a 1 a1只要满足 G T M I G^TM I GTMI的条件我们就可以说 G G G是我们最终需要的矩阵进一步计算 G T M I ⟷ G ( M − 1 ) T G^TM I \longleftrightarrow G (M^{-1})^T GTMI⟷G(M−1)T 最终可得将法线从模型空间转换到世界空间的矩阵为 ( M − 1 ) T (M^{-1})^T (M−1)T。
补充说明
当模型矩阵只进行了旋转或等比缩放时我们用这个矩阵来变换法线向量可以得到正确的结果。
这是因为旋转矩阵和等比缩放矩阵都是正交矩阵正交矩阵有一个属性矩阵的转置等于矩阵的逆。
因此 M − 1 M T → G ( M − 1 ) T M M^{-1} M^T \rightarrow G (M^{-1})^T M M−1MT→G(M−1)TM
参考
https://learnopengl-cn.github.io/02%20Lighting/02%20Basic%20Lighting/
http://www.lighthouse3d.com/tutorials/glsl-12-tutorial/the-normal-matrix/