# 为什么Whitted光线追踪还不够：全局光照与路径追踪的诞生

从Whitted的常数环境光到渲染方程，蒙特卡洛路径追踪如何用随机采样让颜色溢出、软阴影和焦散自然出现

> 全局光照 · 渲染原理 · 路径追踪 · 约 5 分钟 · 07 月 10 日

## 本篇要点

1. Whitted 光线追踪只追踪镜面反射和折射方向，用常数环境光代替漫反射之间的间接光照——这是它画面不够真实的核心原因。
2. 渲染方程用一个积分统一了所有光照（直接+间接），但无法解析求解。
3. 路径追踪用蒙特卡洛方法随机采样方向，通过大量路径的平均值逼近真实光照——颜色溢出、软阴影、焦散是同一个模拟过程的自然产物，不是额外添加的 hack。
4. 代价是巨大的计算量：每个像素需要成百上千条随机路径，否则图像布满噪点；直到近年硬件加速+降噪才走进实时游戏。

---

上一篇我们讲到，Whitted 光线追踪从像素出发，递归追踪反射、折射和阴影光线，让镜面反射和玻璃折射变得真实自然。但如果你玩过打开了光线追踪的游戏，可能注意过另一个细节：房间角落的阴影不是一团死黑，墙壁的颜色会"染"到旁边的物体上，游泳池底有闪烁的光斑——这些效果，Whitted 光线追踪做不出来。

这一篇，我们就来补上这块拼图：**全局光照**，以及实现它的核心算法——**蒙特卡洛路径追踪**。

## Whitted 做不到的事：漫反射间接光

Whitted 光线追踪在交点处发射三种次级光线：反射光线（只沿完美镜面方向）、折射光线（只沿完美折射方向）、阴影光线（指向光源）。[1]

这个设计的局限很明显：它只追踪了**镜面反射**和**折射**这两种特殊方向。对于**粗糙表面**（漫反射）之间的相互光照，它完全不管——直接用一个常数"环境光（ambient）"代替。[2]

但真实世界不是这样的。你房间里的墙面、地板、天花板之间，光线在无数粗糙表面之间反复弹射。一面红墙会把红色光线反射到旁边白色的物体上，让白墙的底部也带上淡淡的红色——这叫**颜色溢出（color bleeding）**。这些效果，Whitted 算法完全模拟不出来。

这就引出了**全局光照（global illumination, GI）**的概念：渲染计算中，不仅要考虑光线从光源直接打到物体（直接光照），还要考虑光线在物体间弹射一次、两次、甚至更多次之后才到达某个点的**间接光照**。[3]

## 渲染方程：用一个公式描述所有光照

1986年，James Kajiya 提出了**渲染方程（rendering equation）**，第一次用数学公式完整描述了光在场景中的传播：

$$L_o(p, \omega_o) = L_e(p, \omega_o) + \int_{\Omega^+} L_i(p, \omega_i) f_r(p, \omega_i, \omega_o) (\omega_i \cdot n) \, d\omega_i$$

翻译成大白话：一个点发出（或反射）向某个方向的光，等于它自己发出的光，加上从所有方向射入的光被表面反射后贡献的总和。[2][3]

这个方程漂亮地统一了所有光照——直接光照、间接光照、镜面反射、漫反射，全都在里面。但问题是：**这个积分几乎不可能解析求解**。被积函数本身依赖于场景中其他点的光照，而其他点的光照又依赖于更多的点……这是一个无限维的递归积分。

## 蒙特卡洛路径追踪：用随机采样逼近真相

Kajiya 在同一篇论文里给出了解法：**路径追踪（path tracing）**。核心思路是：既然无法精确计算积分，那就用**蒙特卡洛方法**——随机采样，用大量样本的平均值来逼近真实值。[1][2]

具体怎么做？

1. 从相机出发，穿过像素，发射一条主光线，打到场景中的第一个交点
2. 在这个交点处，**随机选择一个方向**（而不是像Whitted那样只选镜面方向），发射一条新光线
3. 新光线撞到下一个物体，再随机选一个方向继续……直到光线碰到光源，或者飞出场景——这就形成了一条完整的**路径**（从光源到相机的完整光路）
4. 对每个像素，重复这个流程成百上千次（每次方向都是随机选的），把所有这些路径贡献的颜色取平均

关键的区别就在第二步：Whitted 在交点处只发射**固定方向**的次级光线，路径追踪在交点处**随机选择方向**。[3]

这意味着路径追踪能捕捉到**所有方向的光照**——包括从漫反射表面弹射过来的间接光。一条路径可能走：相机 → 白墙 → 红墙 → 光源，这条路径就会把红墙的红色"带到"白墙上。

![路径追踪示意图：每步随机选择方向，形成从相机到光源的完整路径](https://pbr-book.org/4ed/Light_Transport_I_Surface_Reflection/pha13f05.png)

## 为什么这能让画面"突然变真"？

三种 Whitted 做不了、但路径追踪能自然产生的效果：

**颜色溢出（color bleeding）**：红色墙壁旁边的白色物体底部泛红。这是光线从红墙弹到白墙再弹到相机的结果——路径追踪随机采样方向时，会"撞到"这种路径。Whitted 的常数环境光永远不会产生这种效果。[4]

**软阴影（soft shadows）**：真实世界的光源有面积，阴影边缘是从清晰到模糊的渐变。路径追踪从交点向光源区域随机采样——有些采样点被挡住（阴影），有些没被挡住（亮部），平均下来就产生自然的半影过渡。Whitted 的阴影光线只射向光源中心一点，只能产生硬邦邦的边界。[1]

**焦散（caustics）**：光线穿过玻璃杯或水面，被折射/反射聚焦后在地面形成亮斑。路径追踪中，光线从光源出发，经过玻璃的折射，再被地面漫反射，最终进入相机——这条路径会被随机采样捕捉到。Whitted 的镜面-漫反射路径组合，它处理不了。[5]

## 代价：噪声与时间

路径追踪的代价是巨大的。每个像素需要成百上千条随机路径才能得到一张干净图像。如果路径数量不够，图像会布满**噪点**——就像在暗光下用手机拍照时那种颗粒感。

1986年 Kajiya 用路径追踪渲染一张图，分辨率不高，跑了**数小时**。即使到今天，电影《阿凡达》《冰雪奇缘》里每一帧都是用路径追踪离线渲染的，一帧需要**数十分钟到数小时**。[1][2]

直到2018年之后，RTX显卡的硬件加速加上**降噪技术（denoising）**，才让路径追踪在实时游戏中、在有限采样数下勉强跑起来——但那是下一个话题了。

## 小结

Whitted 光线追踪能处理镜面反射和折射，但靠环境光常数"糊弄"了漫反射之间的间接光照。路径追踪用蒙特卡洛方法随机采样方向，在渲染方程的框架下统一处理所有光照——代价是巨大的计算量。颜色溢出、软阴影、焦散这些让画面"突然变真"的效果，在路径追踪里不是额外添加的，而是同一个模拟过程的自然产物。

## 来源

1. [GAMES101 — 路径追踪章节，蒙特卡洛解渲染方程、间接光照、俄罗斯轮盘赌](https://caterpillarstudygroup.github.io/GAMES101_mdbook/RayTracing/PathTracing.html)
2. [Kajiya 1986 — The Rendering Equation，首次提出渲染方程与路径追踪的经典论文](https://www.cs.princeton.edu/courses/archive/fall03/cs526/papers/kajiya86.pdf)
3. [UC Berkeley CS184 — Global Illumination & Path Tracing 课件，渲染方程推导与路径追踪伪代码](https://cs184.eecs.berkeley.edu/sp26/assets/lectures/13-global-illumination-path-tracing.pdf)
4. [Cornell Box — 物理测量基准场景，展示颜色溢出等全局光照效果](https://bowers.cornell.edu/cornell-box)
5. [PBRT 4th Edition — Path Tracing 章节，路径构造与蒙特卡洛估计](https://pbr-book.org/4ed/Light_Transport_I_Surface_Reflection/Path_Tracing)

---

原文：https://pangzhengboyin.com/articles/global-illumination-and-path-tracing-d0f8906e

> **庞征博引** · 想学的，慢慢都会
>
> 庞征博引是把想学的东西写成连载的 AI 学习工具。说出想学什么，它会先了解你的基础，再把主题写成一篇篇 5–10 分钟能读完的文章；边读边问，接下来学什么跟着你走。这篇就是这样写出来的。
>
> 开始你自己的连载 → https://pangzhengboyin.com
