1. Bump Mapping(凹凸贴图)
在图形学中,每个表面都有一个法向量(Normal Vector),它定义了光线如何与表面交互。在光照计算中,凹凸效果通常通过这些法向量与光线方向的交互来表现。
Bump Mapping(凹凸贴图)相较于普通的纹理,其存储的不是颜色值,一般是使用一张灰度图来存储一系列模型顶点相对于表面的高度信息,并以该高度信息来“扰动”表面法线方向,因此也叫高度贴图(height map)。
灰度值越小表示该位置的表面相对于原表面越向外凸起,灰度值越大表示该位置的表面相对于原表面越向内凹陷。但时刻记住,凹凸映射是通过改变表面法线方向来改变光照结果,表面几何信息没有任何变化。
Bump Mapping 的本质是:
- 不改变表面的实际几何形状。
- 通过修改法向量来模拟表面细节。
这种方式避免了直接增加几何复杂度,从而减少计算成本。
2. 关键概念与数据结构
2.1 高度图 (Height Map)
- 高度图是 Bump Mapping 的核心输入。
- 它是一个灰度纹理图,用像素值(灰度值)表示表面高度变化。
- 灰度值范围:0(最低点)到 1(最高点)。
- 每个像素的高低差会影响法向量的扰动。
2.2 法向量扰动
法向量的扰动由高度图的梯度信息计算得出:
- 在每个像素的周围,计算高度变化的梯度。
- 根据梯度修改表面初始法向量,从而模拟凹凸效果。
2.3 切线空间 (Tangent Space)
为了方便计算和实现,Bump Mapping 通常在切线空间中操作。任何坐标空间都由三个互相正交的基向量构成,切线空间也是如此。
- 切线空间是以每个顶点为中心定义的局部坐标系,由三个互相正交的基向量T,B,N组成。
- 顶点的法向量 N N N(Normal) (z轴)
- 顶点的切线向量 T T T(Tangent) (x轴)
- 副切线向量 B B B(Bitangent)由法线和切线叉乘得到 ( y轴)
- 切线空间的优点是:
- 任何法线扰动都可以用相对坐标(相对于当前表面)表达。
- 与高度图或法线图纹理配合方便。
3. Bump Mapping 的数学原理
3.1 梯度计算
给定一个高度图 h ( u , v ) h(u, v) h(u,v),其中 u , v u, v u,v 是纹理坐标,梯度的计算如下:
- 沿 u u u 方向的偏导数:
∂
h
∂
u
≈
h
(
u
+
Δ
u
,
v
)
−
h
(
u
,
v
)
\frac{\partial h}{\partial u} \approx h(u + \Delta u, v) - h(u, v)
∂u∂h≈h(u+Δu,v)−h(u,v)
2. 沿
v
v
v 方向的偏导数:
∂ h ∂ v ≈ h ( u , v + Δ v ) − h ( u , v ) \frac{\partial h}{\partial v} \approx h(u, v + \Delta v) - h(u, v) ∂v∂h≈h(u,v+Δv)−h(u,v)
3.2 扰动后的法向量
法向量 N ′ N' N′ 的计算公式:
N ′ = N − k ⋅ ( ∂ h ∂ u ⋅ T + ∂ h ∂ v ⋅ B ) N' = N - k \cdot ( \frac{\partial h}{\partial u} \cdot T + \frac{\partial h}{\partial v} \cdot B ) N′=N−k⋅(∂u∂h⋅T+∂v∂h⋅B)
- N N N:原始法向量。
- k k k:比例因子(控制扰动的强度)。
- T , B T, B T,B:切线和双切线向量。
- 最后, N ′ N' N′ 必须单位化(normalization)。
3.3 光照计算
- 使用修改后的法向量 N ′ N' N′ 计算光照。
- 基本光照公式(以 Blinn-Phong 模型为例):
I
=
k
d
(
L
⋅
N
′
)
+
k
s
(
R
⋅
V
)
n
+
k
a
I = k_d (L \cdot N') + k_s (R \cdot V)^n + k_a
I=kd(L⋅N′)+ks(R⋅V)n+ka
-
k
d
,
k
s
,
k
a
k_d, k_s, k_a
kd,ks,ka:漫反射、镜面反射、环境光系数。
-
L
L
L:光源方向。
-
V
V
V:视线方向。
-
R
R
R:反射方向。
通过扰动法向量 N ′ N' N′,可以改变光照与表面的交互,从而产生凹凸不平的效果。
4. Bump Mapping 的实现步骤
4.1 获取 TBN 矩阵
- TBN 矩阵 (Tangent-Bitangent-Normal Matrix) 是将切线空间 (Tangent Space) 的向量转换为世界空间 (World Space) 的变换矩阵。
- 包含:
- 切线向量 (Tangent Vector, T T T):与纹理的 u u u 方向对齐。
- 副切线向量 (Bitangent Vector, B B B):与纹理的 v v v 方向对齐。
- 法向量 (Normal Vector, N N N):原始表面的法线。
4.2 采样高度差
- 使用高度贴图 (Height Map) 在纹理坐标
u
,
v
u, v
u,v 附近的像素高度进行采样:
- h ( u , v ) h(u, v) h(u,v) 是当前片段的高度值。
- h ( u + 1 / w , v ) h(u+1/w, v) h(u+1/w,v) 是 u u u 方向上一个像素的高度值。
- h ( u , v + 1 / h ) h(u, v+1/h) h(u,v+1/h) 是 v v v 方向上一个像素的高度值。
4.3 计算扰动
- 计算纹理坐标方向的高度变化:
- d U = k h ⋅ k n ⋅ ( h ( u + 1 / w , v ) − h ( u , v ) ) dU = k_h \cdot k_n \cdot (h(u+1/w, v) - h(u, v)) dU=kh⋅kn⋅(h(u+1/w,v)−h(u,v))
- d V = k h ⋅ k n ⋅ ( h ( u , v + 1 / h ) − h ( u , v ) ) dV = k_h \cdot k_n \cdot (h(u, v+1/h) - h(u, v)) dV=kh⋅kn⋅(h(u,v+1/h)−h(u,v))
- 构造局部空间中的扰动法向量:
- l n = ( − d U , − d V , 1 ) l_n = (-dU, -dV, 1) ln=(−dU,−dV,1)。
4.4 转换到世界空间
- 使用 TBN 矩阵将局部扰动法向量映射到世界空间:
- n world = normalize ( T B N ⋅ l n ) n_{\text{world}} = \text{normalize}(TBN \cdot l_n) nworld=normalize(TBN⋅ln)。
4.5 光照计算
- 用更新后的法向量进行光照计算(例如 Blinn-Phong 模型),以渲染出凹凸的光影效果。
4.5 渲染输出
结合法向量扰动后的光照结果,渲染最终画面。
5. Bump Mapping 的优化技术
5.1 Normal Mapping
Bump Mapping 的改进版本,它直接使用法线图(Normal Map)来存储预计算的法向量信息:
- 优势:避免实时计算梯度,性能更高。
- 应用:几乎所有现代游戏都使用 Normal Mapping。
5.2 Parallax Mapping
进一步增强视觉效果,加入纹理坐标的偏移:
- 思路:模拟视差效果,使细节更加真实。
- 成本:计算复杂度更高。
5.3 Displacement Mapping
通过修改顶点位置来改变几何形状,产生真实的凹凸:
- 优势:凹凸细节会影响模型轮廓。
- 成本:需要更高的多边形数和渲染性能。
6. Bump Mapping 的实际应用
6.1 游戏开发
- 表面细节:如石头、砖墙、金属表面的细节。
- 角色建模:皮肤纹理、服装褶皱。
6.2 虚拟现实
通过增强表面细节,提高沉浸感。
6.3 电影特效
模拟复杂材质表面(如鳞片、裂纹)。
6.4 建筑可视化
通过 Bump Mapping 模拟材质纹理,减少几何复杂度,提升实时渲染效率。