法线贴图
为什么需要切线空间

为什么需要法线贴图

物体模型由成百上千个平坦的三角形围成.
三角形上附加纹理的方式来增加额外细节. 提升真实感.

但是近看时,就有问题了.变成平面.缺乏细节.
原因:

  • 物体表面并非平坦的. 而是表示出无数(凹凸不平的)细节.

如果以光的视角来看这个问题:
是什么使表面被视为完全平坦的表面来照亮?

  • 答案会是 表面的法线向量

从光照的角度考虑:
只有一件事决定物体的形状.那就是垂直与它的法向量!

  1. 如果一个表面只有一个法线向量.那么表面就按这个法向量的方式被一种方式照亮.
  2. 如果每个Fragment拥有不同的法线. 就能对细微的细节进行改变.
    每个fragment使用了自己的法线,可以让光照相信一个表面由很多微小的(垂直于法线向量的)平面所组成,物体表面的细节将会得到极大提升。

这种每个fragment使用各自的法线替代一个面上所有fragment使用同一个法线的技术叫做 法线贴图(normal mapping)或凹凸贴图(bump mapping)
图形学基础 | 法线贴图

法线贴图

为使法线贴图工作,我们需要为每个fragment提供一个法线。

范围转换

法线向量的范围在-1到1之间
由于纹理的rgb的颜色在[0,1]之间.我们需要把其映射到 [-1,1]之间.

// 从法线贴图范围[0,1]获取法线 
normal = texture(normalMap, fs_in.TexCoords).rgb; 
// 将法线向量转换为范围[-1,1] 
normal = normalize(normal * 2.0 - 1.0);

很多法线图都是蓝色的.
因为基本上法线都是指向正z轴.
图形学基础 | 法线贴图

方向问题

  • 法线图的方向的固定的. 但是法线贴图可以贴到不同的部位上.
  • 若不同,那么法线贴图可能就会错误.
    图形学基础 | 法线贴图

有一个可行的方法就是 为每个表面制作一个单独的法线贴图。
但是如果模型有无数个朝向不同的表面. 那么还是不可行.

另一个稍微有点难的解决方案是,
在一个不同的坐标空间中进行光照
这个坐标空间里,法线贴图向量总是指向这个坐标空间的正z方向;
所有的光照向量都相对与这个正z方向进行变换。这样就能 始终使用同样的法线贴图,不管朝向问题。

这个坐标空间叫做 切线空间(tangent space)

切线空间

法线贴图中的法线向量在切线空间中, 法线永远指向正Z方向.

图形学基础 | 法线贴图
切线空间是位于三角形表面之上的空间

  • 法线相对于单个三角形的本地参考

  • 它们都被定义为指向正z方向,无论最终变换到什么方向

  • 使用一个 特定的矩阵 能将 本地/切线空间中的法线向量转成世界或视图坐标,使它们转向到最终的贴图表面的方向

  • 法线贴图被定义在切线空间中,解决问题的方式是计算出一种矩阵,把法线从切线空间变换到一个不同的空间,这样它们就能和表面法线方向对齐了

  • 切线空间的一大好处是我们可以 为任何类型的表面计算出一个这样的矩阵把切线空间的z方向和表面的法线方向对齐

这种矩阵叫做 TBN矩阵 这三个字母分别代表tangent、bitangent和normal向量。
这是建构这个矩阵所需的向量。需要三个相互垂直的向量,它们沿一个表面的法线贴图对齐于:上、右、前

已知上向量是表面的法线向量
右和前向量是 切线(Tagent)和副切线(Bitangent)向量

计算出切线和副切线并不像法线向量那么容易。
切线和副切线与纹理坐标的两个方向对齐

通过法线贴图我们已经有了N.
需要计算B和T.计算需要什么信息:

  • 用一个三角形的顶点和纹理坐标 (因为纹理坐标和切线向量在同一空间中)
    图形学基础 | 法线贴图
  • 这需要计算出 delta纹理坐标矩阵的逆矩阵
    图形学基础 | 法线贴图
    从技术上讲,顶点着色器中无需副切线。
    所有的这三个TBN向量都是相互垂直的用T和N向量的叉乘计算出副切线:vec3 B = cross(T, N);

切线空间法线贴图

  • 先将所有TBN向量变换到我们所操作的坐标系. (如世界空间. 那么就是乘以 Model矩阵). 但其实也可以不做变换. 我们只关心向量的方向.

  • 创建实际的TBN矩阵. vs_out.TBN = mat3(T, B, N);

  • 现在有了 TBN矩阵. 如何使用:

  1. 直接使用TBN矩阵. 这个矩阵可以把切线坐标空间的向量转换到世界坐标空间. 直接将采样得到的法线向量乘以TBN矩阵. 这样所有法线和其他光照变量就在同一个坐标系中了.
  2. 也可以使用TBN矩阵的逆矩阵. 这个矩阵可以把世界坐标空间的向量转换到切线坐标空间。

One More Thing

TBN向量可能会不能互相垂直,这意味着TBN矩阵不再是正交矩阵了。法线贴图可能会稍稍偏移

  • 使用叫做格拉姆-施密特正交化过程(Gram-Schmidt process)的数学技巧,我们可以对TBN向量进行重正交化,这样每个向量就又会重新垂直了

相关文章:

  • 2021-10-07
  • 2022-01-18
  • 2021-05-18
  • 2021-08-10
  • 2021-04-21
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-12-26
  • 2022-12-23
  • 2021-12-24
  • 2022-01-21
相关资源
相似解决方案