zoukankan      html  css  js  c++  java
  • 关于 BumpMap 和 NormalMap 原理细节中的 Tangent Space 和 TBN 矩阵

      这篇文章假使你已经对 BumpMap 和 NormalMap 的流程有基本的了解。

      这两天因为项目需要又复习了下 NormalMap 的原理细节,一年多以前细细看过一次,到现在忘了很多,可是当初又没有写笔记,所以在纠结细节的这两天因为数学差而特别痛苦。

      BumpMap 和 NormalMap 说起来大家都非常熟悉,但就是就我个人而言,初次分析背后的原理有很多容易混淆的地方,对于爱钻牛角尖的人很是折磨。

      BumpMap 出现早,主要使用灰度图(高度图),实时计算法线,过程就和生成法线图的过程一样,利用相邻像素点的高度差向量叉撑计算法线,这个过程比较简单没有异议,有了法线之后的计算和 NormalMap 一致,对于 BumpMap 的的理论,找到了一篇40多页的论文:A Practical and Robust Bump-mapping Technique for Today's GPU,我现在是实在没时间去琢磨看完它。

      对于 NormalMap 的使用,其中最重要的莫过于 Object Sapce (物体坐标系) 和 Tangent Space (切线坐标系,也称切线空间) 之间的转换过程,以及转换矩阵 TBN 矩阵。第一次接触是《Introduction to 3D Game Programming with DirectX 9.0c—A Shader Approach》这本书:假设 T, B, N 分别为相对于 Object Space 的沿着切线空间的 x, y, z 坐标轴的向量,那么从 Tangent Space 到 Object Space 的转换矩阵为:

                                      | Tx    Ty    Tz |

          MΔ = [T, B, N]T =   | Bx    By   Bz |

                                      | Nx    Ny   Nz |

    假设 MΔ 为正交矩阵,那么从 Object Space 到 Tangent Space 的转换矩阵为:

                                                                   | Tx    Bx   Nx |

         M = MΔ-1 = ([T, B, N]T)-1 = [T, B, N] =   | Ty    By   Ny |

                                                                   | Tz    Bz   Nz |

      然后预生成每个顶点的 T, B, N。

      可能大家到这里就会觉得ok了,但是如果你看到了这篇文章《Derivation of the Tangent Space Matrix》,数学不好的人也许就会凌乱,因为在这里从 Tangent Spane 到 Object Space 的变换矩阵 M 与上面那本书里讲到的是相反的。即 MΔ = [T, B, N], M = MΔ-1 。(这篇文章讲解的 TBN 部分,与《Mathematics for 3D Game Programming and Computer Graphics》的第7.8节讲解的完全一致)。更有意思的是,我发现有人和我有同样的疑问,发在了 Ogre 论坛:http://www.ogre3d.org/forums/viewtopic.php?f=10&t=54827,比较早了2009年的,遗憾的是下面的回复都没有戳中他的点。

      那这两种说法到底谁正确呢?从 Tangent Spane 到 Object Space 的变换矩阵到底是 [T, B, N] 还是 [T, B, N]T 呢?答案是全都正确!

      因为看到这里线代学得不好的人很容易忽略一个条件就是:整个运算过程中使用的向量是行向量还是列向量行向量左乘矩阵,列向量右乘矩阵。假设 T, B, N 是相对于 Local Space 的 Tangent Space 自身的坐标轴, 那么相对 Tangent Space 自身三个坐标轴自然是 T,(1, 0, 0),B,(0, 1 , 0), N,(0, 0, 1) ,这时有以下公式

          对于使用行向量:[T,, B,, N,]T M = [T, B, N]T

                           =>   [(1, 0, 0),(0, 1 , 0), (0, 0, 1)] M = [T, B, N]T

                           =>   M = [T, B, N]T

          对于使用列向量:M [T,, B,, N,]= [T, B, N]

                           =>   M [(1, 0, 0),(0, 1 , 0), (0, 0, 1)][T, B, N]

                           =>   M = [T, B, N]

      很明显,《Introduction to 3D Game Programming with DirectX 9.0c—A Shader Approach》一书中使用的是行向量,从 Tangant Space 到 Object Space 的计算过程为:

          Vobject = Vtangent M = [Xtangent, Ytangent, Ztangent] [T, B, N]T;

          Vtangent = Vobject M-1 ,如果 M 正交,则有:

          Vtangent = Vobject M-1= Vobject MT

                      = [Xobject, Yobject, Zobject] [T, B, N]

                      = [Vobject dot T, Vobject dot B, Vobject dot N]

      而《Derivation of the Tangent Space Matrix》和 《Mathematics for 3D Game Programming and Computer Graphics》中使用的是列向量,尤其是前者的矩阵都是使用的左乘,那么计算过程为:

          VobjectT = M VtangentT = [T, B, N] [Xtangent, Ytangent, Ztangent]T;

          VtangentT = M-1 VobjectT ,如果 M 正交,则有:

          VtangentT = M-1 VobjectT = MT VobjectT

                       = [T, B, N]T [Xobject, Yobject, Zobject]T

                       = [VobjectT dot TT, VobjectT dot BT, VobjectT dot NT]

      通过以上对比,是不是一目了然,而且无论怎样转换,最终还有一个可以检验的就是,从 Object Space 到 Tangent Space 转换一个向量的最终结果一定是,该向量分别与 T, B, N 三个向量分别点乘,作为新的 Tangent Space 中向量的三个分量,从以上的Vtangent的最终结果就可以看到。

      额外补充,容易搞混的还有一点就是一旦假设 TBN 矩阵正交,那凌乱就来了,本来由于行向量和列向量就已经使 [T, B, N] 和 [T, B, N]T 的使用对于新手来说完全乱了阵脚,这个正交完全就是来捣乱的,所以建议新手完全忽略 TBN 矩阵的正交,记住 M = MΔ-1 就够了。Derivation of the Tangent Space Matrix》和 《Mathematics for 3D Game Programming and Computer Graphics》这两个都是到最后才说到正交化 TBN 概念,前面都是硬算 MΔ-1,所以它们介绍的理论更纯正,但细节也更复杂些。

      好了,以上就是这两天纠结理解的结果,下一篇我将再分享一下根据顶点位置和 uv 坐标计算具体的 TBN 矩阵时一些细节的理解。

     
  • 相关阅读:
    could not detect mdm peripheral on hardware
    学习zynq的一些感受
    sdk添加新的C文件编译出错
    linux下驱动webcam
    转:fatal error: SDL/SDL.h: No such file or directory
    转:Unknown module(s) in QT: multimedia
    HFSS设计导入AD中
    REST(Representational state transfer)的四个级别以及HATEOAS介绍
    Servlet CDI Example Analysis
    Introduction and use of Cookie and Session(Cookie&Session的介绍和使用)
  • 原文地址:https://www.cnblogs.com/yaukey/p/normalmap_tangentspace_tbn.html
Copyright © 2011-2022 走看看