我们都知道gl的坐标系统。它的工作是将坐标从一个坐标系转到另一个坐标系。其中我们用到了几个转换矩阵。其中最为重要的是模型(Model)、视图(View)、投影(Projection)三个矩阵。因为涉及光线光照部分的计算通常都在eye space中进行计算,所以我们需要把坐标转换到eye space中,否则基于眼睛位置的效果(比如镜面反射)就很难实现。一般通过以下代码将vertex到 eye space:
vertexEyeSpace = gl_ModelViewMatrix * gl_Vertex;

为什么我们不能对法向量(normal vector)进行同样的运算来转换到 eye space 呢?首先,法向量(normal vector)是一个三维向量,而 ModelView 是一个 44 的矩阵。其次,因为法向量代表方向,我们想要做的就是将该方向变换到 eye space 中。那么我们是否可以直接用modelView左上角的 33 矩阵来做这个变换呢?如果可以,我们只需要用下面的代码就可以完成变换:
normalEyeSpace = vec3(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));

很遗憾,上面的变换只适用于某些情况。这也是因此我们引入了 gl_NormalMatrix 的原因。

我们先来推导下gl_NormalMatrix:

首先我们来看下下面这张图:

 

 

其中N是我们的法向量,T是三角形的切向量。那么我们想要求的gl_NormalMatrix应该满足变换前后方向不变。假设变换后的切向量为T’,变换后的法向量为N’。所以应该满足:

T’ * N’ = T * N = 0。

下面是推导过程:

c代表因为,s代表所以:

c:
T = (P2 - P1) s: ModelView * T = ModelView * (P2 - P1) = ModelView * P2 - ModelView * P1 = P2' - P1' => ModelView * T = T' c: N' = NormalMatrix * N T' = ModelView * T T' * N' = T * N = 0 s: (NormalMatrix * N) · (ModelView * T) = 0 => transpose(NormalMatrix * N) * (ModelView * T) //向量点积,相当于把一个向量转置再乘以另外一个向量 transpose(N) * transpose(NormalMatrix) * ModelView * T = 0 c: N * T = 0 //因为N与T点积为0,也就是transpose(N)*T为0(点积相当于转置一个向量后乘以另外一个向量),所以上面式子中间部分为单位矩阵,因为向量乘以单位矩阵等于自身,即transpose(NormalMatrix)*ModelView=单位矩阵I s: transpose(NormalMatrix) * ModelView = I => NormalMatrix = transpose((ModelView)^(-1))


即NormalMatrix是ModelView矩阵逆的转置。

我们也可以看到,当M(ModelView)矩阵为正交矩阵时(即M的转置等于M的逆)时,法向量变换阵(NormalMatrix)等于M阵。这就是上文所说的特例。

重要结论:
NormalMatrix是ModelView矩阵逆的转置

参考:
http://www.lighthouse3d.com/tutorials/glsl-12-tutorial/the-normal-matrix/

作者:雨幻逐光

链接:https://www.jianshu.com/p/e001aec29976

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

原文地址:http://www.cnblogs.com/DvsJ/p/16813888.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性