关于 BumpMap 和 NormalMap 原理细节中的 Tangent Space 和 TBN 矩阵 II

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

  这篇文章的只是来源依然是:《Derivation of the Tangent Space Matrix》和《Mathematics for 3D Game Programming and Computer Graphics》的7.8节。我讨论的细节为TBN矩阵的计算。

  任意一个Mesh的三角形在是 Local Space 和 Tangent Space 中如图1所示:

  

                                       图1

  图1左侧彩色坐标系为 Local Space,右侧为三角形所在的 Tangent Space,v0, v1, v2 分别为三个顶点在 Local Space 中的坐标点,c1, c2, c3 分别为三个顶点的uv坐标。这其中选v0点作为 Tangent Space 中的原点O,T,B 分别对齐纹理空间的 u,v 坐标轴。

  那么对于三角形中任意一点 Q(vq, cq),一定有:

  Q - O = vq - v0 = (cqT - c0T) T + (cqB - c0B) B,其中 cqT,cqT,c0B,c0B,分别是 cq 和 c0 点的 u,v 分量。

  这个公式其实就是把向量 v0->vq 在 Tangent Space 中从 u,v 两个方向把这个向量进行分解,(cqT - c0T) 和 (cqB - c0B) 是标量,可以理解为基础向量 T 和 B 的缩放系数。

 

图2

  这样对于任意三角形 Δp0p1p2,以 p0 为原点,则有

  Q1 = p1 - p0

  Q2 = p2 - p0

  =>

  Q1 = p1 - p0 = (c1T - c0T) T + (c1B - c0B) B
  Q2 = p2 - p0 = (c2T - c0T) T + (c2B - c0B) B

  理解以上这几步非常重要,尤其是分解向量到 T,B 方向。那现在继续处理这个公式:

      |Q1x   Q1y   Q1z|

      |Q2x   Q2y   Q2z|

  =

  |(c1T - c0T)   (c1B - c0B)|   | T |

  |(c2T - c0T)   (c2B - c0B)|   | B |

  =

  |(c1T - c0T)   (c1B - c0B)|   |Tx   Ty   Tz|

  |(c2T - c0T)   (c2B - c0B)|   |Bx   By   Bz|

   对公式稍做变化,得到:
 
  |Tx   Ty   Tz|
  |Bx   By   Bz|
  =
  |(c1T - c0T)   (c1B - c0B)|-1   |Q1x   Q1y   Q1z|
  |(c2T - c0T)   (c2B - c0B)|     |Q2x   Q2y   Q2z|
 
  所以到这里就搞定了 T,B 两个向量,这两个向量属于三角形 Δp0p1p2 单个顶点的向量需要根据公用它的三角形各自计算出的值加权,但如果两个相邻三角形的 uv 坐标不连续,则中间这条边上的顶点的 T,B 向量在计算加权时会被重复计算,所以这样的顶点计算出的 T,B 不参加加权计算,以免误差。最后算 N 只需简单使用:N = T x B 即可。(关于加权这一步我自己没有去深究具体方法,只是参照原文理解后翻译了下)
  但是以上计算出的 TBN 矩阵并不一定是相互垂直,或者是单位向量,但是可以使用施密特正交化来使得其近似正交,并且结果的误差在可接受范围内,这样得到的 TBN 矩阵的逆矩阵可以直接认为是其转置矩阵,方便计算。关于这个计算后面还有些细节这里就不讨论了,《Mathematics for 3D Game Programming and Computer Graphics》的7.8节中有讲述,但我自己并没有去推倒那一步,感兴趣的同学自己可以试试。
  现在有了这些理论,我可以更进一步去处理项目中与此相关的那些衍生的纹理计算效果了。
 
posted @ 2013-06-04 21:37  yaukey  阅读(1415)  评论(0编辑  收藏  举报