2、BRDF的数学定义:辐射度量学基础

好,咱们正式开始啃BRDF。很多同学一看到数学公式就头大,其实别怕。BRDF的数学定义,说白了就是描述「一束光打过来,有多少光反射到了你眼睛的方向」。我当年刚入行时也觉得这东西太抽象,直到有一次做汽车漆面渲染,怎么调参数都不对,最后回头重新捋了一遍辐射度量学,才发现是基础概念搞混了。

这一节,咱们先把辐射度量学的几个核心物理量讲清楚,然后自然引出BRDF的正式定义。

2.1 辐射度量学四大金刚

辐射度量学是图形学里描述光能量的数学工具。你不需要成为物理学家,但必须搞懂下面这四个量。我习惯把它们叫做「四大金刚」:

物理量 符号 单位 一句话理解
辐射通量 Φ W(瓦特) 光源每秒发出的总能量
辐照度 E W/m² 单位面积接收到的能量
辐射亮度 L W/(m²·sr) 单位面积、单位立体角内的能量
立体角 ω sr(球面度) 二维角在三维空间的扩展

核心记忆点:辐照度E是「到达」表面的光,辐射亮度L是「从表面离开或穿过」的光。BRDF就是连接这两者的桥梁。

2.2 辐射通量(Φ)—— 总能量

辐射通量是最基础的量。它表示光源在单位时间内辐射出的总能量,单位是瓦特(W)。

举个例子:一个100W的灯泡,它的辐射通量就是100W。当然,实际灯泡有一部分能量转化成了热能,但概念上就是这么回事。

在渲染中,我们很少直接操作辐射通量,但它是一切推导的起点。你想想看,没有总能量,后面那些「单位面积」「单位立体角」就无从谈起。

2.3 辐照度(E)—— 单位面积的能量

辐照度描述的是:单位面积上接收到的辐射通量。

公式很简单:

E = dΦ / dA

其中dA是微分面积。单位是W/m²。

这里有个关键点:辐照度只关心「到达」表面的光,不关心光从哪个方向来。它是个标量,把所有方向的光通量累加起来。

我的经验:做PBR材质时,辐照度经常被用来计算漫反射光照。你只需要知道「有多少光打到了这个点」,而不需要知道具体方向——这正是漫反射的特性。

2.4 辐射亮度(L)—— 带方向的能量

辐射亮度比辐照度多了一个维度:方向。它描述的是单位面积、单位立体角内的辐射通量。

公式:

L = d²Φ / (dA · dω · cosθ)

这里多了两个东西:

  • dω:微分立体角,表示一个极小的方向锥
  • cosθ:表面法线与光线方向的夹角余弦,用于面积投影

为什么要乘cosθ?因为当光线斜着照射表面时,同样的光束覆盖了更大的面积,单位面积接收到的能量自然就少了。这个投影因子在图形学里无处不在。

辐射亮度的单位是W/(m²·sr),其中sr是球面度(立体角的单位)。

注意:辐射亮度是渲染方程中最核心的量。你看到的最终像素颜色,本质上就是辐射亮度的数值映射。我曾经在项目中遇到一个bug,就是因为把辐照度和辐射亮度搞混了,结果整个场景的亮度都不对——排查了整整两天。

2.5 立体角(ω)—— 三维的角度

立体角是二维角在三维空间的推广。一个完整的球面对应的立体角是4π sr。

微分立体角的计算公式:

dω = sinθ dθ dφ

其中θ是极角,φ是方位角。这个公式在半球积分中会反复出现。

你不需要死记硬背,但要知道:立体角是用来描述「方向锥」大小的。在BRDF中,入射方向和出射方向都是用立体角来描述的。

2.6 BRDF的正式定义

好了,有了上面的基础,BRDF的定义就水到渠成了。

BRDF的全称是Bidirectional Reflectance Distribution Function(双向反射分布函数)。它的正式定义是:

f(ωi, ωr) = dLr(ωr) / dEi(ωi)

其中:

  • ωi:入射方向(光来的方向)
  • ωr:出射方向(观察方向)
  • dLr(ωr):出射方向上的微分辐射亮度
  • dEi(ωi):入射方向上的微分辐照度

说白了,BRDF就是回答一个问题:从ωi方向来的光,有多少被反射到了ωr方向?

注意,这里用的是微分形式。BRDF描述的是「单位入射辐照度」产生的「出射辐射亮度」。它是一个比值,单位是1/sr。

重要性质:

  • 非负性:f(ωi, ωr) ≥ 0(能量不能为负)
  • 能量守恒:所有出射方向的积分 ≤ 1(反射的能量不能超过入射的能量)
  • 互易性:f(ωi, ωr) = f(ωr, ωi)(交换入射和出射方向,结果不变)

互易性这个性质很有意思。它意味着BRDF在物理上是可逆的:光从A方向打到B方向,和从B方向打到A方向,反射特性是一样的。我在做双向路径追踪时,这个性质帮了大忙——可以复用很多计算结果。

2.7 知识结构图

下面这张图帮你理清辐射度量学和BRDF的关系:

辐射度量学与BRDF知识结构 辐射通量 Φ 辐照度 E = dΦ/dA 辐射亮度 L 立体角 ω BRDF f(ωi, ωr) = dLr / dEi 出射辐射 Lr(ωr) 入射辐照 Ei(ωi) 💡 核心逻辑: 辐射通量 → 辐照度(单位面积)→ 辐射亮度(单位面积+单位立体角)→ BRDF(比值)

2.8 实战中的注意事项

搞清楚了定义,咱们聊聊实际项目中容易踩的坑:

  • 单位混淆:辐照度和辐射亮度单位不同,千万别直接加减。我见过有人把E和L直接相加,结果画面亮得离谱。
  • cosθ因子:很多BRDF实现里忘了乘cosθ,导致掠射角(grazing angle)处的能量异常。检查你的渲染方程,看看有没有遗漏这个投影项。
  • 立体角积分:做蒙特卡洛积分时,立体角的采样权重一定要算对。我曾经因为立体角公式写错,导致整个半球采样结果偏了30%。

调试技巧:如果你不确定自己的BRDF实现是否正确,可以用一个简单的Lambertian漫反射模型做验证。它的BRDF值是常数 ρ/π(ρ是反射率),如果连这个都算不对,那肯定是辐射度量学的基础出了问题。