土法炼钢兴趣小组的算法知识备份

游戏中的数学 (9) - 光照模型

目录

引言

光照是计算机图形学的灵魂。虽然现代引擎使用复杂的 PBR (Physically Based Rendering),但理解经典的光照模型仍然是基础。 经典光照模型通常由三部分组成: \[ Color = Ambient + Diffuse + Specular \]

Lighting Models

1. 漫反射 (Diffuse) - Lambert

漫反射模拟的是粗糙表面(如砖墙、布料)对光的散射。 光线照射到表面后,向四面八方均匀反射。 强度取决于光线方向 \(\vec{L}\) 与表面法线 \(\vec{N}\) 的夹角。

\[ I_{diffuse} = \max(0, \vec{N} \cdot \vec{L}) \]

2. 镜面反射 (Specular) - Phong

镜面反射模拟的是光滑表面(如金属、塑料)的高光 (Highlight)。 它取决于观察方向 \(\vec{V}\) 和反射方向 \(\vec{R}\) 的夹角。

\[ \vec{R} = \text{reflect}(-\vec{L}, \vec{N}) \] \[ I_{specular} = (\max(0, \vec{R} \cdot \vec{V}))^{shininess} \]

3. 改进模型 - Blinn-Phong

Phong 模型有一个缺点:计算反射向量 \(\vec{R}\) 比较昂贵。 Jim Blinn 提出了一种优化:使用半程向量 (Halfway Vector) \(\vec{H}\)\(\vec{H}\) 是光线方向 \(\vec{L}\) 和观察方向 \(\vec{V}\) 的中间向量。

\[ \vec{H} = \text{normalize}(\vec{L} + \vec{V}) \] \[ I_{specular} = (\max(0, \vec{N} \cdot \vec{H}))^{shininess} \]

4. 环境光 (Ambient)

为了模拟间接光照(光线在墙壁间反弹),经典模型简单地加上一个常数颜色。 \[ I_{ambient} = K_a \] 这是一种非常粗糙的近似,现代游戏通常使用全局光照 (GI) 或环境光遮蔽 (AO) 来替代。

5. PBR 基础 (Physically Based Rendering)

现代游戏引擎(Unity URP/HDRP, Unreal)默认使用 PBR。它比 Blinn-Phong 更符合物理规律。

能量守恒 (Energy Conservation)

出射光线的能量不能超过入射光线的能量。 漫反射和镜面反射是互斥的:光线要么进入物体内部(漫反射),要么被表面反弹(镜面反射)。 \[ k_D + k_S \le 1 \] 物体越光滑(金属),镜面反射越强,漫反射就越弱(看起来越黑)。

菲涅尔效应 (Fresnel Effect)

观察一下你身边的物体(比如桌子或手机屏幕)。当你垂直看它时,反光可能不强;但当你以近乎平行的角度(掠射角)看它时,反光会变得非常强烈,像镜子一样。 这就是菲涅尔效应。 Schlick 近似公式: \[ F(\theta) = F_0 + (1 - F_0)(1 - \cos\theta)^5 \] 其中 \(F_0\) 是基础反射率(垂直观察时的反射率)。

Shader 代码示例 (HLSL/GLSL)

// 输入: N (法线), L (光照方向), V (观察方向)
vec3 N = normalize(Normal);
vec3 L = normalize(LightDir);
vec3 V = normalize(ViewDir);

// Diffuse
float diff = max(dot(N, L), 0.0);

// Specular (Blinn-Phong)
vec3 H = normalize(L + V);
float spec = pow(max(dot(N, H), 0.0), 32.0);

// Result
vec3 color = (ambient + diff + spec) * objectColor;

总结


< 上一篇: 渲染管线 | 回到目录 | 下一篇: 曲线数学 >


By .