zoukankan      html  css  js  c++  java
  • Opengl的gl_NormalMatrix

    原文地址:http://blog.csdn.net/ichild1964/article/details/9728357

    参考:http://www.gamedev.net/topic/598985-gl-normalmatrix-in-glsl-how-to-calculate/

    当用glsl传normal到fragment的时候总要用gl_Normal* gl_NormalMatrix,是为什么呢?做bumpmap的时候,binormal和tangent需不需要也乘以gl_NormalMatrix呢,如果需要把TBN转到世界空间,而不是把灯光转到TBN的话需不需要乘以gl_NormalMatrix或者是需要乘以其它矩阵?有没有想过perspective投影之后模型成什么样子呢?在Direct3D你不需要关心这些,因为都处理好了,所以一路稀里糊涂下来效果也基本上做的出来,在OpenGL就不行了。下面解释了什么是 gl_NormalMatrix,简而言之gl_NormalMatrix是为了令法线在perspective projection之后和投影后的模型平面依然垂直,但是它并不是投影矩阵哦,而是投影矩阵的逆矩阵的翻转矩阵惊恐 。呵呵,顺便想象下投影后的物体是什么样子吧,这样就会幡然醒悟为什么需要重新找垂直于平面的发现了。

    Normal Matrix

    Normals are funny.  They're vec3's, since you don't want perspective on normals.   And they don't actually scale quite right--a 45 degree surface with a 45 degree normal, scaled by glScalef(1,0.1,1), drops the surface down to near 0 degrees, but actually tilts the normal *up*, in the opposite direction from the surface, to near 90 degrees.

    Mathematically, if between two points a and b on the surface, dot(n,b-a)==0, then after applying a matrix M to the points, you want the normal to still be perpendicular.  The question is, what matrix N do you have to apply to the normal to make this happen?  In other words, find N such that
        dot( N * n , M * a - M * b) == 0

    We can solve this by noting that dot product can be expresed as matrix multiplication--dot(x,y) = transpose(x) * y, where we treat an ordinary column-vector as a little matrix, and flip it horizontally.  So
       transpose(N * n) * (M*a - M*b) == 0         (as above, but write using transpose and matrix multiplication)
       transpose(N * n) * M * (a-b) == 0              (collect both copies of M)
       transpose(n) * transpose(N) * M * (a-b) == 0    (transpose-of-product is product-of-transposes in opposite order)

    OK.  This is really similar to our assumption that the original normal was perpendicular to the surface--that dot(n,b-a) == transpose(n) * (a-b) == 0.  In fact, the only difference is the new matrices wedged in the middle.  If we pick N to make the term in the middle the identity, then our new normal will be perpendicular to the surface too:
        transpose(N) * M == I   (the identity matrix)
    This is the definition for matrix inverses, so the "normal matrix" N = transpose(inverse(M)).

    If you look up the GLSL definition for "gl_NormalMatrix", it's defined as "the transpose of the inverse of the gl_ModelViewMatrix".  Now you know why!

  • 相关阅读:
    (转) 网络流之最大流算法(EdmondsKarp)
    如何在面试中发现优秀程序员
    Java中Volatile关键字详解
    比AtomicLong还高效的LongAdder 源码解析
    AtomicInteger的用法
    synchronized详解
    Java内部锁的可重用性(Reentrancy)
    Java可重入锁
    关于原生javascript的this,this真是个强大的东东
    js时间戳怎么转成日期格式
  • 原文地址:https://www.cnblogs.com/dragon2012/p/4875144.html
Copyright © 2011-2022 走看看