深入理解能量守恒定律与微平面理论(Cook-Torrance 模型)------物理渲染的数学基础
01什么是 BRDF?
双向反射分布函数(Bidirectional Reflectance Distribution Function,BRDF) 是描述光线如何从不透明表面反射的核心数学工具。它量化了从某一入射方向 ωᵢ 照射到表面上,有多少能量会沿出射方向 ωₒ 反射出去。
BRDF 是现代**基于物理的渲染(Physically Based Rendering, PBR)**的核心,它让计算机生成图像达到了照片级真实感。

数学定义
BRDF 在数学上定义为出射辐射亮度(Radiance)对入射辐照度(Irradiance)的微分比值:

- Lₒ(ωₒ)沿方向 ωₒ 的出射辐射亮度(W·sr⁻¹·m⁻²)
- Lᵢ(ωᵢ)沿方向 ωᵢ 的入射辐射亮度(W·sr⁻¹·m⁻²)
- θᵢ入射光方向与表面法线之间的夹角
- dωᵢ入射方向对应的立体角微元(sr)
🔑 关键性质
BRDF 具有亥姆霍兹互易性(Helmholtz Reciprocity):交换入射和出射方向,值不变。即 f(ωᵢ, ωₒ) = f(ωₒ, ωᵢ)。这一性质保证了物理一致性。
02能量守恒:物理渲染的基石
能量守恒要求:反射出去的光能量总量不能超过入射的光能量。这是 BRDF 合法性的最基本物理约束,也是区分"物理正确"渲染与经验渲染的核心差异。
半球积分约束
将 BRDF 在整个上半球积分,得到方向半球反射率(Directional Hemispherical Reflectance),其值必须 ≤ 1:


⚠️ 为什么 Blinn-Phong 不满足能量守恒?
传统 Blinn-Phong 模型的高光项 (n·h)^s 没有归一化因子,当粗糙度降低(光泽度 s 增大)时,高光亮度会无限增加。Cook-Torrance 模型通过分母项 4(n·ωᵢ)(n·ωₒ) 确保了能量守恒。
03微平面理论:表面模型
**微平面理论(Microfacet Theory)**假设宏观表面由无数微小、光学平滑的"微面元(microfacet)"组成。每个微面元都是一个完美的镜面,有自己的法线方向。宏观表面的粗糙度由这些微面元法线的统计分布决定。

三大效应
🔬
法线分布(NDF)
统计描述微面元法线指向半向量 h 的概率密度。粗糙度越低,分布越集中,高光越尖锐。
🌑
自阴影(Shadowing)
微面元可能被相邻面元遮挡入射光(shadowing)或遮挡出射光(masking),产生几何衰减。
💡
菲涅耳效应(Fresnel)
光在表面与介质边界的反射率取决于入射角。掠射角(接近 90°)时反射率趋近 100%。
04Cook-Torrance BRDF 详解
Cook-Torrance 模型将 BRDF 分解为漫反射(Diffuse) 与**镜面反射(Specular)**两部分:

其中漫反射项为朗伯(Lambertian)模型,镜面反射项为微平面模型:

- D(h)法线分布函数(Normal Distribution Function):描述微面元法线与半向量对齐的概率密度
- F(ωᵢ, h)菲涅耳方程(Fresnel Equation):描述不同入射角下的反射率
- G(ωᵢ, ωₒ)几何遮蔽函数(Geometry Function):描述微面元的自遮挡效应
- 4(n·ωᵢ)(n·ωₒ)归一化因子:确保能量守恒的分母项
05三大核心函数
D --- GGX/Trowbridge-Reitz 法线分布
GGX 分布是目前工业界最广泛使用的 NDF,其"长尾"特性能产生真实的高光拖尾效果:


F --- Schlick 菲涅耳近似
菲涅耳方程描述了反射率随入射角变化的规律。Schlick 近似在保持高精度的同时大幅降低计算量:


G --- Smith 几何遮蔽函数
Smith 方法将阴影(shadowing)和遮蔽(masking)分开计算,再相乘。配合 GGX 使用 Schlick-GGX 近似:

06完整 GLSL 实现
以下是完整的 Cook-Torrance BRDF 在 GLSL(OpenGL/WebGL)中的实现:
cs
// =============================================
// GGX 法线分布函数 (Normal Distribution)
// =============================================
float DistributionGGX(vec3 N, vec3 H, float roughness) {
float a = roughness * roughness;
float a2 = a * a;
float NdotH = max(dot(N, H), 0.0);
float NdotH2 = NdotH * NdotH;
float denom = NdotH2 * (a2 - 1.0) + 1.0;
denom = PI * denom * denom;
return a2 / denom; // D_GGX
}
// =============================================
// Smith-Schlick 几何遮蔽函数
// =============================================
float GeometrySchlickGGX(float NdotV, float roughness) {
float r = roughness + 1.0;
float k = (r * r) / 8.0; // 直接光照用此公式
return NdotV / (NdotV * (1.0 - k) + k);
}
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) {
float NdotV = max(dot(N, V), 0.0);
float NdotL = max(dot(N, L), 0.0);
float ggx1 = GeometrySchlickGGX(NdotV, roughness); // masking
float ggx2 = GeometrySchlickGGX(NdotL, roughness); // shadowing
return ggx1 * ggx2; // G_Smith
}
// =============================================
// Schlick 菲涅耳近似
// =============================================
vec3 FresnelSchlick(float cosTheta, vec3 F0) {
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
}
cs
// =============================================
// 完整 Cook-Torrance PBR 渲染
// =============================================
vec3 CookTorranceBRDF(
vec3 N, // 表面法线
vec3 V, // 视线方向
vec3 L, // 光源方向
vec3 albedo, // 漫反射颜色
float metallic, // 金属度 [0,1]
float roughness // 粗糙度 [0,1]
) {
vec3 H = normalize(V + L); // 半向量
// ---- 菲涅耳基值 F0 ----
// 绝缘体 F0 ≈ 0.04,金属 F0 = albedo
vec3 F0 = mix(vec3(0.04), albedo, metallic);
// ---- Cook-Torrance 镜面项 ----
float NDF = DistributionGGX(N, H, roughness); // D 项
float G = GeometrySmith(N, V, L, roughness); // G 项
vec3 F = FresnelSchlick(max(dot(H, V), 0.0), F0); // F 项
float NdotL = max(dot(N, L), 0.0);
float NdotV = max(dot(N, V), 0.0);
vec3 numerator = NDF * G * F;
float denominator = 4.0 * NdotV * NdotL + 0.0001; // 防除零
vec3 specular = numerator / denominator;
// ---- 能量守恒拆分 ----
// kS = 镜面比例 = F;kD = 漫反射比例 = 1 - kS
vec3 kS = F;
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic); // 金属无漫反射
vec3 diffuse = kD * albedo / PI; // 朗伯漫反射
// ---- 最终 BRDF 输出 ----
return (diffuse + specular) * NdotL;
}
07参数对比与视觉效果
Cook-Torrance BRDF 主要受以下三个参数控制,其组合决定了材质的外观:
| 参数 | 范围 | 视觉效果 | 典型材质 |
|---|---|---|---|
| roughness (粗糙度) | 0.0 --- 1.0 | 0 = 镜面清晰高光;1 = 完全漫射 | 镜面/塑料/混凝土 |
| metallic (金属度) | 0.0 --- 1.0 | 0 = 绝缘体(白色高光);1 = 金属(彩色高光) | 木材/铁/金 |
| F0 (基础反射率) | 0.02 --- 1.0 | 绝缘体 ≈ 0.04;半导体 ≈ 0.3;金属 ≈ albedo | 玻璃/硅/铜 |
| albedo (漫反射色) | vec3 [0,1]³ | 绝缘体的漫反射颜色;金属的镜面颜色 | 任意颜色 |

💡 PBR 工作流小结
实际 PBR 渲染管线中,roughness、metallic、albedo 通常以纹理贴图的形式输入,允许单个模型表面有复杂的材质变化。Cook-Torrance BRDF 结合 IBL(基于图像的光照)和实时阴影贴图,已成为当今游戏引擎(UE5、Unity HDRP)和离线渲染器(Arnold、Cycles)的标准材质模型。