DongGu
全局光照与路径追踪

全局光照与路径追踪

前面我们介绍了辐射度量学的相关知识,并推导出了渲染方程:

用算子形式可以展开为:

如果我们能够同时计算出直接光照与所有间接光照,就得到了全局光照。用一个简单的公式概括:

然而,渲染方程中包含了对整个半球空间的连续积分,计算机无法直接求解。接下来,我们将介绍蒙特卡洛积分路径追踪,用数值方法来实现具有物理真实感的全局光照渲染。

概率密度函数(PDF)

在介绍蒙特卡洛积分之前,我们需要补充一点概率论的基础知识。

概率密度函数与累积分布函数

对于一个连续型随机变量 ,由于其取值有无限不可数个,它取任意单点值的概率皆为

为了量化连续变量的概率分布,我们定义累积分布函数(CDF, Cumulative Distribution Function) 为:

概率密度函数(PDF, Probability Density Function),则是 CDF 的一阶导数:

根据微积分基本定理,随机变量 落在区间 内的概率,由 在该区间上的定积分给出:

PDF 满足两大数学公理性质:

  1. 非负性
  2. 规范性(全概率为 ):

蒙特卡洛积分

蒙特卡洛采样示意

对于渲染方程,我们需要对无数个入射方向进行积分——但这对计算机来说是不可能的。我们有什么办法能将连续的积分转换成离散的求和?

积分的几何意义是函数图像下的面积。受此启发:如果我们随机对函数进行采样,计算每个采样点附近微小区域的面积并求和,随着采样点越来越多,结果会越来越接近真实积分值:

其中 是函数值(高度), 是微小的宽度, 是采样数目。

这种利用随机采样来估计积分的方法,就是蒙特卡洛积分(Monte Carlo Integration)。

均匀随机采样

如果我们使用均匀随机采样,每个采样点 在区间 中被选中的概率相等。此时,每个采样点代表的宽度为 ,于是:

均匀采样的缺点是效率低下——无论函数值在何处变化剧烈,采样密度都相同。

重要性采样

想象这样一个函数图像:大部分点对应的函数值都为 ,只有极少数点对应的函数值不为 。如果我们均匀随机采样,大量采样结果都是 ,只有极少数采到了真正重要的位置。

这会导致:有时候采到了重要位置,结果很大;有时候没采到重要位置,结果很小。我们将这种大幅波动称为噪声

为了减少噪声,我们改变采样策略——对重要区域多采样,其他区域少采样。这就是重要性采样(Importance Sampling)。

但非均匀采样会引入偏差——重要区域被过度采样,则计算结果会偏大。为了修正这种偏差,我们引入概率密度函数 PDF。

通过 PDF,我们知道每个采样点被选中的概率。对于每一次采样,我们将其贡献除以其对应的采样概率并求平均,便可修正偏差:

  • 重要区域采样多,采样概率高,除以采样概率后贡献被压低。
  • 非重要区域采样少,采样概率低,除以采样概率后贡献被放大。

于是,我们得到了通用的蒙特卡洛积分公式

其中: - 是从概率密度函数 中采样得到的随机变量。 - 被采样到的概率密度。 - 是采样次数。 越大,估计值越接近真实积分值,误差按 收敛。

蒙特卡洛积分公式的推导与正确性证明

蒙特卡洛估计量 的正确性可以通过无偏性来证明。我们计算它的数学期望:

由于每个 独立同分布,考虑单个样本的期望:

因此:

的数学期望恰好等于真实积分值,所以蒙特卡洛估计是无偏的。这正是蒙特卡洛积分得以广泛应用的数学根基。

路径追踪

我们已经掌握了如何用蒙特卡洛积分来估计一个积分。对于任意积分 ,都可以写成离散求和的形式:

回到渲染方程:

将其积分部分与蒙特卡洛积分公式建立对应关系:

蒙特卡洛积分 渲染方程
入射方向
方向采样的 PDF

代入蒙特卡洛公式,得到:

现在我们终于可以计算出一个着色点反射到摄像机的光线了。

递归光线追踪示意

而且,这个过程可以递归进行——因为 点的入射光线,恰恰就是 点的反射光线。这意味着我们可以递归地追踪整条光路。

光线爆炸问题

光线爆炸问题

然而,这里有一个严重的问题:为了计算 点的颜色,我需要向半球面随机射出 条光线去采样 点(图形学中约定所有光线方向都由着色点向外指)。而每一个 点,为了计算它自身的颜色,又需要射出 条光线……

这会导致指数爆炸——第 次弹射将产生 条光线,计算量无法承受。

解决方案简单而激进:。每次在着色点的半球面上只随机射出一条光线。

这样一条线走到底,就形成了一条路径(Path)——这就是”路径追踪”名字的来源。

带来了三个新问题:

  1. 画面噪点严重——单条路径的估计方差太大。
  2. 无线递归——没有终止条件,光线会无限弹射。
  3. 效率低下——光线盲目乱射,很难碰到小光源。

下面,我们依次解决这三个问题。

画面噪点问题

多 SPP 路径追踪

解决噪点的方法不是在同一个”着色点”上做多次采样,而是向同一个像素内射入多条路径(如 256、1024 条),每条路径各自独立地在场景中弹射。最后将该像素所有路径的颜色取平均值,噪点就被抹平了。

这个技术称为 SPP(Samples Per Pixel,每像素采样数)。

不同 SPP 效果对比

如上图所示,高 SPP(右)相比低 SPP(左),画面明显更加平滑清晰,噪点显著减少。

无限递归问题

光线在场景里弹跳,如果不加限制,它会无限弹跳下去。但如果硬性规定”弹跳 5 次就停”,能量会被截断,画面变暗——这是有偏的。

我们采用俄罗斯轮盘赌(Russian Roulette, RR)来解决。

每次光线打到表面后,我们以概率 决定继续弹跳,并以概率 直接终止。关键在于:如果继续弹跳,返回的结果要除以 ,以补偿那些被终止的光线。

这样得到的期望值是准确的:

俄罗斯轮盘赌保证了结果在数学期望上是无偏的,同时使递归深度自然趋近于有限——经过 次弹跳后继续的概率为 ,很快就趋近于

盲目乱射问题

如果场景里有一个很小的灯泡,按照我们目前的算法——在着色点半球面上随机选一个方向()——大概率是碰不到这个灯泡的。这就导致射了 1000 条路径,可能 990 条都是黑的,画面噪点极大。

我们将光线的计算分为两部分来解决这个问题:

  • 直接光(Direct Light):直接在光源表面上随机挑一个点 ,从 点连一条线过去。这部分直接处理光源贡献。
  • 间接光(Indirect Light):在半球面上随机射一条光线(沿用之前的 RR 逻辑)。这部分递归处理。

变量替换:从立体角到光源面积

对于直接光的计算,我们不再在半球立体角上盲目采样,而是直接在光源的表面积 上进行均匀采样。这种方法叫作光源采样(Light Sampling)。

但问题在于:原始渲染方程是对立体角 积分的,而我们现在希望对光源表面积 积分。数学上,你不能拿着一个在 域上采样的样本,直接代入一个对 域积分的公式里。我们必须进行积分变量换元

立体角与面积微元的转换

如图,我们在光源表面上选取面积微元 ,从着色点 看过去:

  1. 遮挡检测:首先判断 之间是否存在遮挡,如果被遮挡则不计算该光源样本。

  2. 倾斜修正:光源表面不一定垂直于 的连线。设光源法线为 ,连线方向为 (从 指向 ),光线的反方向为 ,两者夹角记为 。我们需要把 投影到垂直于光线的方向上:

  3. 距离衰减:根据立体角的物理定义(立体角 = 面积 / 距离的平方):

于是得到了立体角微元与面积微元的转换公式。将它代入原始渲染方程,直接光部分的积分从对半球 变为对光源表面积

光源采样的蒙特卡洛估计

我们在光源表面均匀抽样一个点 ,其概率密度为 为光源总面积)。代入蒙特卡洛公式:

,得到单样本的直接光采样公式

至此,我们完整解决了路径追踪的三个核心问题,实现了物理上完全正确的全局光照。

Cornell Box 对比

如上图所示,路径追踪渲染出的 Cornell Box(右)与真实照片(左)几乎无法分辨——这正是渲染方程的威力所在。

总结

回顾全文,我们从渲染方程出发,逐步构建了全局光照的数值求解框架:

  1. 概率密度函数(PDF) 提供了描述随机变量分布的工具,是蒙特卡洛积分的数学基础。
  2. 蒙特卡洛积分将连续积分转化为离散求和——通过对被积函数进行随机采样,并用 PDF 修正非均匀采样的偏差,能够在任意维度上给出无偏估计。
  3. 路径追踪将蒙特卡洛积分应用于渲染方程——每次弹射只射出一条光线形成路径,通过每像素多条路径(高 SPP)压制噪点,通过俄罗斯轮盘赌终止递归,通过光源采样高效计算直接光照。
  4. 全局光照不再是遥不可及的目标——借助路径追踪,直接光照与间接光照被统一在同一个蒙特卡洛框架下求解,最终产出了与真实照片难以区分的渲染结果。

这次的插图来自画师 夏套

图片地址:https://www.pixiv.net/artworks/145990124

本文作者:DongGu
本文链接:https://donggu.xyz/2026/06/26/图形学入门/全局光照与路径追踪/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可