在圖形學中,向量是描述幾何、光照、運動等核心概念的基礎工具。以下是向量在圖形學中的關鍵應用和深入解析:
1. 向量的核心作用
- 幾何表示:描述點、方向、法線、切線等。
- 空間變換:平移、旋轉、縮放等操作依賴向量運算。
- 光照計算:光線方向、反射向量、點積用于漫反射和鏡面高光。
- 物理模擬:速度、加速度、力的合成與分解。
2. 圖形學中的向量運算
(1) 點積(Dot Product)的應用
- 光照模型:計算光線與表面法線的夾角(Lambert漫反射):
I = max ? ( 0 , L ? N ) ? I light I = \max(0, \mathbf{L} \cdot \mathbf{N}) \cdot I_{\text{light}} I=max(0,L?N)?Ilight?
L 為光線方向 \ {L}為光線方向 ?L為光線方向, N 為法線 \ {N}為法線 ?N為法線, I light 為光強 I_{\text{light}}為光強 Ilight?為光強 - 背面剔除:若視線向量(\mathbf{V})與法線(\mathbf{N})的點積(\mathbf{V} \cdot \mathbf{N} > 0),則表面不可見。
- 投影計算:將向量投影到另一向量(如陰影生成)。
(2) 叉積(Cross Product)的應用
- 法向量計算:通過三角形兩邊的叉積求法線:
N = ( v 1 ? v 0 ) × ( v 2 ? v 0 ) \mathbf{N} = (\mathbf{v}_1 - \mathbf{v}_0) \times (\mathbf{v}_2 - \mathbf{v}_0) N=(v1??v0?)×(v2??v0?) - 坐標系構建:生成切線空間(TBN矩陣)用于法線貼圖:
T = 切線 , B = N × T \mathbf{T} = \text{切線}, \quad \mathbf{B} = \mathbf{N} \times \mathbf{T} T=切線,B=N×T
(3) 歸一化(Normalization)
- 將向量轉換為單位向量,確保方向計算不受長度影響:
v ^ = v ∣ v ∣ \hat{\mathbf{v}} = \frac{\mathbf{v}}{|\mathbf{v}|} v^=∣v∣v?
(關鍵用于光線方向、法線等)
3. 向量在圖形流水線中的角色
(1) 頂點處理
- 模型變換:通過矩陣乘法(如MVP矩陣)將頂點從模型空間轉換到裁剪空間:
v clip = M V P ? v model \mathbf{v}_{\text{clip}} = \mathbf{MVP} \cdot \mathbf{v}_{\text{model}} vclip?=MVP?vmodel? - 法線變換:法線需用模型矩陣的逆轉置矩陣變換,以保持垂直性:
N world = ( M ? 1 ) ? ? N model \mathbf{N}_{\text{world}} = (\mathbf{M}^{-1})^\top \cdot \mathbf{N}_{\text{model}} Nworld?=(M?1)??Nmodel?
(2) 光照與著色
- Phong模型:結合環境光、漫反射(點積)、鏡面反射(反射向量計算):
R = 2 ( L ? N ) N ? L \mathbf{R} = 2(\mathbf{L} \cdot \mathbf{N})\mathbf{N} - \mathbf{L} R=2(L?N)N?L - 半程向量(Blinn-Phong):優化鏡面高光計算:
H = L + V ∣ L + V ∣ \mathbf{H} = \frac{\mathbf{L} + \mathbf{V}}{|\mathbf{L} + \mathbf{V}|} H=∣L+V∣L+V?
(3) 屏幕空間操作
- 視口變換:將NDC坐標映射到屏幕像素坐標:
{ x screen = ( x ndc + 1 ) ? width 2 y screen = ( 1 ? y ndc ) ? height 2 \begin{cases} x_{\text{screen}} = (x_{\text{ndc}} + 1) \cdot \frac{\text{width}}{2} \\ y_{\text{screen}} = (1 - y_{\text{ndc}}) \cdot \frac{\text{height}}{2} \end{cases} {xscreen?=(xndc?+1)?2width?yscreen?=(1?yndc?)?2height??
4. 圖形學特有問題與優化
(1) 精度問題
- 浮點誤差:使用高精度浮點(如
double
)或誤差容忍比較(如glm::epsilonEqual
)。 - 歸一化失效:零向量或極小向量的保護性處理:
if (length(v) < 1e-6) discard;
(2) 向量插值
- 重心坐標插值:在三角形內插值頂點屬性(顏色、UV、法線):
p = α v 0 + β v 1 + γ v 2 \mathbf{p} = \alpha \mathbf{v}_0 + \beta \mathbf{v}_1 + \gamma \mathbf{v}_2 p=αv0?+βv1?+γv2? - 透視校正插值:在投影空間中需除以深度(
w
分量)保證正確性。
(3) 性能優化
- SIMD指令:使用SSE/AVX加速向量運算(如Unity的Burst編譯器)。
- 預計算向量:如預生成環境貼圖的輻照度向量。
5. 實際代碼示例(GLSL/HLSL)
(1) 法線貼圖解碼
vec3 normal = texture(normalMap, uv).xyz * 2.0 - 1.0; // 從[0,1]映射到[-1,1]
normal = normalize(TBN * normal); // TBN為切線空間矩陣
(2) 反射光線計算
vec3 reflectDir = reflect(-lightDir, normal);
float specular = pow(max(dot(viewDir, reflectDir), 0.0), 32.0);
(3) 屏幕空間UV計算
vec2 screenUV = gl_FragCoord.xy / resolution;
6. 擴展:向量在高級圖形技術中的應用
- 光線追蹤:光線方向向量與場景求交(如
rayDir = normalize(target - origin)
)。 - SDF(符號距離場):利用向量計算點到表面的最短距離。
- 流體模擬:速度場(向量場)的平流與擴散。