原文
以下内容都是基于原文的阅读以及总结
如图
可以发现在光照下, 石砖并没有呈现凹凸的样子, 并不符合真实实际的情况
实际情况是石砖上会有凹凸起伏,以光的角度思考为什么我们看到瓷砖会有凹凸起伏.
是什么使表面被视为完全平坦的表面来照亮?答案会是表面的法线向量。
以光照算法的视角考虑的话,只有一件事决定物体的形状,这就是垂直于它的法线向量。砖块表面只有一个法线向量,表面完全根据这个法线向量被以一致的方式照亮。如果每个fragment都是用自己的不同的法线会怎样?这样我们就可以根据表面细微的细节对法线向量进行改变;这样就会获得一种表面看起来要复杂得多的幻觉:
每个fragment使用了自己的法线,我们就可以让光照相信一个表面由很多微小的(垂直于法线向量的)平面所组成,物体表面的细节将会得到极大提升。这种每个fragment使用各自的法线,替代一个面上所有fragment使用同一个法线的技术叫做法线贴图(normal mapping)或凹凸贴图(bump mapping)。应用到砖墙上,效果像这样:
你可以看到细节获得了极大提升,开销却不大。因为我们只需要改变每个fragment的法线向量,并不需要改变所有光照公式。现在我们是为每个fragment传递一个法线,不再使用插值表面法线。这样光照使表面拥有了自己的细节。
法线贴图
将法线的x, y, z转化成对应的r, g, b信息存储的2D的纹理中, 并且因为x, y, z是[-1, 1], *0.5 + 0.5重新映射为[0, 1]即可
存在一定问题
⬆️(1)
上面这幅图的法线贴图可以贴在下面的模型上.
但是不能贴在平躺着的瓷砖上
上图中瓷砖法线已经变成y方向了, 而采样的到的法线大部分还是z方向, 如下图所示
即: 采样得到的法线本应该朝着绿色方向(y方向), 而实际采样第1图,得到向右的方向,显然错误.
解决方法
- 为模型每个方向都进行法线贴图的制作, 模型上有无数朝向的话, 就不可取
- 在一个不同的坐标空间中进行光照, 在这个坐标空间中, 法线贴图向量总是指向这个空间的正z方向; 所有光照向量都相对与这个正z方向进行变换. 这样我们就能始终使用同样的法线贴图, 不管朝向问题. 这个坐标空间叫做切线空间
上图中的变换矩阵即为TBN矩阵
TBN的计算
假设知道
Δ
U
1
,
Δ
U
2
,
Δ
V
1
,
Δ
V
2
,
E
1
,
E
2
\Delta U_1, \Delta U_2, \Delta V_1, \Delta V2, E_1, E_2
ΔU1,ΔU2,ΔV1,ΔV2,E1,E2向量
那么我们可以将三角形的边E1与E2写成切线向量T和副切线向量B的线性组合:
E
1
=
Δ
U
1
T
+
Δ
V
1
B
E
2
=
Δ
U
2
T
+
Δ
V
2
B
E_1 = \Delta U_1 T + \Delta V_1B\\ E_2 = \Delta U_2 T + \Delta V_2B
E1=ΔU1T+ΔV1BE2=ΔU2T+ΔV2B
展开
求逆
再将逆矩阵展开