随机光线追踪与路径追踪
Stochastic Ray Tracing & Path Tracing
光线追踪用投射光线同时解决可见性问题和光照问题。GEA 从最简单的"眼睛光线 + 着色方程"讲起,逐步加入阴影光线、透射光线、用蒙特卡洛估计渲染方程的随机光线追踪、递归间接光照,再到每次只走一条路径的路径追踪、双向路径追踪和 Metropolis 光传输,最后讨论降噪与光线投射效率(GEA4 卷 II 12.6.3–12.6.5)。
用光线解决可见性
从相机焦点穿过成像平面上的每个像素发射眼睛光线 (eye ray),第一个交点就是该像素可见的表面点 。之后可以用简单的着色方程,也可以再发更多光线、用蒙特卡洛积分求每个点的光照(卷 II 12.6.3.1)。
反向与正向
- 从相机往场景里发光线叫反向光线追踪,方向与真实光子相反;能这样做靠的是辐射亮度沿光线不变(真空中)以及光路可逆(见 辐射度量学与光度学)。
- 从光源往外发、记录打到成像面的光路叫正向光线追踪或光追踪 (light tracing);大部分光线永远打不到相机,单独使用极其浪费,但与反向结合就是双向路径追踪(卷 II 12.6.3.2)。
第一步:眼睛光线 + 着色方程 + 阴影光线
对每个可见点套用 Blinn-Phong 着色方程(见 着色方程与经典光照模型),只是在每个光源项前加可见性函数 :
由向每个光源发阴影光线实现:用光线投射函数 (返回沿 最近的交点),交点就是光源 时 ,否则为 0。眼睛光线常称主光线 (primary ray),阴影光线常称次级光线 (secondary ray),但两类都不止这一种(卷 II 12.6.3.3)。
简单菲涅耳反射
可见点落在透明或半透明材质上时,除了阴影光线,再沿折射后的方向发一条透射光线;它穿出物体后得到新点 ,在那里再用着色方程,结果按菲涅耳反射率 与 的出射亮度混合(卷 II 12.6.3.4,见 菲涅耳反射)。
随机光线追踪:直接光照
想用面光源就必须放弃着色方程、改用渲染方程,并用蒙特卡洛估计其中的积分。因为光线方向是随机的,称为随机光线追踪(卷 II 12.6.3.5):
唯一未知的是入射亮度。它等于交点 沿 的出射亮度。如果暂时假设非自发光表面贡献为 0,只有打中面光源的光线有值,那么这就是只算直接光照,对应光路 L(D|G|S)E(G 为光泽反射,见 渲染方程 的光路表示法)。
原书问题(12.6.3.5):GEA 把" 处的入射亮度等于 沿 的出射亮度"归功于 Helmholtz 互易性。这其实是辐射亮度在真空中沿光线守恒(radiance invariance);Helmholtz 互易性说的是 BRDF 交换入射、出射方向后取值不变 ,两者不是一回事(Pharr 等《Physically Based Rendering》第 4 版 4.1.3、4.3.1 节;Dutré 等《Advanced Global Illumination》2.3 节)。同一误用在 12.2 节也出现过,见 辐射度量学与光度学。
另外,GEA 把这里随机朝半球发出的次级光线也叫"阴影光线"(12.6.3.5、12.6.3.7)。通常"阴影光线"只指从着色点射向光源、判断可见性的光线,随机方向的叫反射光线或 bounce/continuation ray(pbrt 4e 13.1)。
递归光线追踪:间接光照
不再把非自发光点当作 0,而是在那里递归应用整个算法,把它当作"反弹光的发光体",或者想象成另一台虚拟相机里的传感器。直接光照时光线树深度为 1;间接光照时树可以任意深,每一层的次级光线成为下一层的主光线。这样就能覆盖 L(D|G|S)*E,比如红地毯让白墙微微偏暖(卷 II 12.6.3.7)。
终止条件很关键:不停止就是无穷开销;固定最大深度会引入偏差,因为最重要的光路不一定最短;无偏的做法是俄罗斯轮盘赌,见 蒙特卡洛积分与重要性采样。
原书问题(12.6.3.7):GEA 把"有偏图像"解释为"算进太多不重要的光路,而低估或完全忽略更重要的光路",并举例:光源紧贴立方体上方,如果从顶面发出的随机光线大多错过光源,顶面就几乎全黑。按统计定义,偏差是估计器期望值与真值之差 ;只要 PDF 在被积函数非零处都大于 0,采样"大多错过光源"只会造成高方差(噪点),期望值仍正确、仍是无偏的。只有完全不采样某些光路(PDF 为 0、截断深度)才产生偏差(pbrt 4e 2.1.3 "Unbiased estimator";Wikipedia "Bias of an estimator")。
路径追踪
递归光线追踪在每个交点发大量次级光线,开销指数爆炸。既然本来就在做蒙特卡洛,每个交点就不必让结果收敛,只发一条次级光线:从像素出发反弹 次形成一条折线路径,打到光源或被俄罗斯轮盘赌终止为止;每条路径算一次估计器,重复很多次仍会收敛到正确亮度。这就是路径追踪(卷 II 12.6.4.3)。
下图对比两者的光线结构:递归追踪是又宽又深的树,路径追踪每次只有一条链。
flowchart LR
subgraph "递归光线追踪"
C1["像素"] --> A1["交点"]
A1 --> B1["交点"]
A1 --> B2["交点"]
A1 --> B3["交点"]
B1 --> D1[...]
B2 --> D2[...]
end
subgraph "路径追踪"
C2["像素"] --> P1["交点"] --> P2["交点"] --> P3["光源或终止"]
end双向路径追踪与 Metropolis 光传输
- 反向路径追踪本质上是在"搜索"会贡献到图像的光源,可能漏掉重要光路,对光泽高光、漫反射相互反射、焦散等效果吃力;正向追踪反过来是在搜索相机。
- 双向路径追踪同时构造一条眼睛子路径和一条光源子路径,再连接成完整光路。反向追踪中光源是辐射亮度 的源、像素收集它;正向追踪中像素是重要性 (importance) 的源、光源收集它, 是辐射亮度的对偶量,满足形式相同的对偶渲染方程。调节两段的比例可以偏向不同效果:光泽镜面反射主要靠眼睛光线,焦散主要靠光源光线(卷 II 12.6.4.4)。
- Metropolis 光传输 (MLT):对路径追踪得到的每条路径做随机扰动,按启发式判断新路径对图像的贡献决定接受或拒绝,相当于找到重要光路后在附近继续探索(卷 II 12.6.4.5)。
原书问题(12.6.4.4、12.6.4.5):(1) GEA 说正向、反向追踪互为对偶"要归功于 Helmholtz 互易性"。对偶性来自光传输算子与其伴随算子(重要性 满足伴随方程),对不满足互易性的 BSDF(例如带折射的透射)同样成立,只是那时伴随 BSDF 要另外处理(Veach 博士论文《Robust Monte Carlo Methods for Light Transport Simulation》1997,第 3、5 章;pbrt 4e 13.9 节)。(2) GEA 把 MLT 的接受/拒绝说成"启发式"。原始 MLT(Veach & Guibas, SIGGRAPH 1997)用的是 Metropolis–Hastings 规则,接受概率 ,严格保证路径的平稳分布与图像贡献成正比,并不是启发式;只是扰动策略的设计带经验成分。
降噪
交互帧率下每帧光线预算很少,路径追踪图像必然很噪:少数像素亮度正确,夹杂大量过亮或过暗的像素。降噪是一个后处理步骤(卷 II 12.6.5.1):
- 早期方法用启发式组合多种手段插值亮度,并利用反照率纹理等场景信息辅助。GPU 厂商提供现成库,例如 NVIDIA Real-Time Denoisers (NRD) 和 AMD FidelityFX。
- 机器学习降噪:用大量"噪声图 / 干净图"图像对训练卷积神经网络 (CNN)。NVIDIA OptiX AI Denoiser 跑在 Volta 架构引入的张量核心上,张量核心用低精度或混合精度的融合乘加做大规模矩阵乘,以精度换速度和并行度。
光线投射效率
1440p 下每像素一条光线就是三百多万条光线,场景有数百万个三角形,暴力相交测试会达到万亿量级,而且每条光线都要遍历全部三角形数据,对缓存极不友好。提速有三条路:降低单次相交测试的成本、大幅减少测试次数、利用相邻且近乎平行的光线之间的相干性(卷 II 12.6.5.2)。
- 减少光线数:用路径追踪代替暴力递归、多重重要性采样、MLT 等降方差方法;实时渲染中常用光栅化 + 光线追踪的混合方案。
- 包围体层次 (BVH):给几何包上球或 AABB 等更易测试的包围体,按固定数目的邻居逐层合并成树。投射时从根开始,只访问包围体测试通过的子树,到叶子才做光线-三角形测试。复杂度从 降到 ( 为光线数, 为三角形数)。好的 BVH 要求包围体紧、占内存小、测试快,兄弟节点重叠少、树平衡,并在分支度与高度之间取舍(见 空间数据结构)。
- 硬件加速结构:底层是 BVH,但只向程序员暴露两层 TLAS / BLAS,见 硬件光线追踪管线。
PBRT 的视角:光线追踪器的组成与随机游走积分器(PBRT 4e 第 1 章)
PBRT 开篇用一个最小的蒙特卡洛积分器把整个系统串起来,后面各章都是在它基础上提高效率。
为什么几何光学就够了(1.2)
可见光波长只有几百纳米,波动效应在厘米、米尺度的物体上影响很小;而对大于几微米的东西做波动级模拟根本不现实。所以 pbrt 主要用 16 世纪到 19 世纪初建立的、把光当作沿光线传播的粒子的模型,核心操作就是光线追踪。
每个光线追踪器都要模拟的七件事(1.2.1–1.2.7)
- 相机与胶片:针孔相机可以等价地把胶片放到针孔前方同样距离处,此时针孔称为眼睛 (eye);针孔与胶片边缘连成的锥体就是可视体积 (viewing volume)。相机负责把图像上的点变成光线(针孔模型:原点取针孔,方向指向成像平面上的点);胶片负责模拟传感器对不同波长的响应(第 5 章)。
- 光线与物体求交:光线写成 ,。隐式曲面 代入光线方程后只剩 一个未知数,例如原点处半径 的球得到关于 的二次方程 ,取最小正根(见 光线求交测试)。除了交点,还需要法线乃至位置与法线对曲面参数的偏导。借助加速结构,光线追踪常常是 ( 为像素数、 为物体数),但构建加速结构本身至少 (第 7 章,见 空间数据结构)。
- 光的分布:功率为 、向各方向均匀辐射的点光源,在距离 处、与入射方向成 的小面元上的微分辐照度为 ,即余弦衰减与平方反比衰减。光照是线性的,各光源可分开计算再相加,这也是可以只随机采样部分光源的依据(12.6 节)。
- 可见性:从着色点向光源发阴影光线 (shadow ray),比较交点的 与光源的 。
- 表面散射:BRDF 推广到透射为 BTDF,统称 BSDF;出射点与入射点不同的是 BSSRDF(牛奶、大理石、皮肤)。
- 间接光传输:Whitted (1980) 强调递归,从而能画镜面反射和透射;他的算法只在指向光源和完美反射/折射的几个方向上求 ,把积分变成少数方向的求和。
- 光线传播:真空中辐亮度沿光线不变;参与介质既会通过吸收和外散射衰减光(透射率 ),也会通过自发光和内散射增加光(第 11、14 章)。
光传输方程与随机游走估计(1.2.6、1.3.6)
光传输方程(又称渲染方程,见 渲染方程):
RandomWalkIntegrator 在球面上均匀选一个方向 ,用单样本估计积分:
即被积函数乘以 (单位球面积)。 未知,但它正是"沿新光线求原点处入射辐亮度",递归调用自己即可;递归在 maxDepth 处停止(否则镜子大厅可能永不终止),BSDF 与余弦乘积为 0 时提前结束(例如不透射表面上两个方向位于两侧)。从相机反向构建路径之所以成立,是因为 pbrt 所用的光学模型时间可逆。
全部代码二十多行,但缺陷明显:发光面小则大多数路径找不到光;点光源被随机打中的概率为 0,画面全黑;完美镜面方向同样永远采不到(图 1.19 中玻璃杯是黑的,8192 spp 仍有高频噪声)。同样 32 spp、差不多的计算量下,PathIntegrator 的均方误差比它低 54.5 倍(图 1.20)。第 13 章的 SimplePathIntegrator 正是对它的逐步改进(见下文 PBRT 13 章小节)。
渲染主循环(1.3.1–1.3.5)
系统结构(1.3 开头、1.5):pbrt 定义了 14 个关键基础类型(表 1.1:Spectrum、Camera、Shape、Primitive、Sampler、Filter、BxDF、Material、FloatTexture/SpectrumTexture、Medium、Light、LightSampler、Integrator),其中 12 个的接口在 base/ 目录,Primitive 和 Integrator 只在 CPU 上用,定义在 cpu/。只有 Integrator 用传统虚函数,其余多态类型用基于标签的分派(TaggedPointer,细节在游戏开发目录的 C++ 内存布局与对齐页)。第 2–12 章的代码几乎都能同时在 CPU 和 GPU 上跑;第 13、14 章的积分器和本章的 RandomWalkIntegrator 只在 CPU 上(RenderCPU(),并行度等于线程数),第 15 章的 RenderWavefront() 两边都能跑,一次并行处理约一百万个图像样本。几乎所有浮点数都声明为 Float(按编译选项为 float 或 double,单精度通常就够)。Integrator 构造时调用各光源的 Preprocess() 传入场景包围盒,并把"无限远"光源另存一个数组。全书代码约 7 万行。
pbrt 分三个阶段:解析场景文件得到 BasicScene;创建具体对象(如 PerspectiveCamera);执行积分器的主循环。CPU 路径上 ImageTileIntegrator 把图像分块并行,按"波次"取样:前两波每像素 1 个样本,之后每波翻倍直到上限,这样渲染中途就能看到所有像素都有样本的预览。RayIntegrator::EvaluatePixelSample() 的数据流是:Sampler 给出样本 → 胶片按传感器响应把一个均匀数映射成若干波长(默认 4 个,每个像素样本取不同波长,见 光谱渲染)→ Camera 生成带光线微分的相机光线(供纹理抗锯齿用,多样本时按采样率缩放微分)→ Li() 求辐亮度 → 乘相机权重(可模拟暗角)后交给 Film。Integrator::IntersectP() 只判断有无交点,专供阴影光线使用,比求最近交点的 Intersect() 便宜。
简史与生产实践(1.6)
- Blinn 定律:"技术进步,渲染时间不变":算力增长被更复杂的场景和算法吃掉。
- 研究线:Whitted 光线追踪 (1980) → Cook–Torrance 微表面模型 (1981/82) → 辐射度方法 (Goral et al. 1984),因 复杂度和沿阴影边界重新细分的难题,实用有限 → 分布式光线追踪 (Cook et al. 1984:运动模糊、景深、光泽反射、面光源) → Kajiya (1986) 提出光传输积分方程与路径追踪: 的两个球用 IBM 4341(首发价约 28 万美元)算了 7 小时(约 2.6 像素/秒);Kajiya 与 von Herzen (1984) 还把体渲染方程引入图形学→ Veach (1997) 的多重重要性采样、双向路径追踪、Metropolis 光传输。
- 生产线:早期电影只能用光栅化(Reyes),关键原因是它不要求整个场景装进内存;Blue Sky 的短片 Bunny(1998)是早期蒙特卡洛全局光照的例子;2001 年 Arnold 首次亮相,后在索尼影业成为生产级渲染器;RenderMan 后来也按 pbrt 的总体架构重写为物理渲染的光线追踪器 (Christensen 2015)。
- 物理渲染在影视普及的理由是提高美术效率:只有"每像素样本数"一个质量旋钮且天然支持渐进预览;能量守恒的材质换了光照环境仍然正确;光线追踪的阴影省去调阴影贴图分辨率和偏移的麻烦,反弹光照自然得到。
- 图 1.16 的奥地利皇冠场景(约 350 万三角形、6 个按实测光谱发光的面光源):最初用 LuxRender(源自 pbrt-v1 的分支)在四核 CPU 上每像素 1280 样本跑了 73 小时;现代 GPU 上 pbrt 以同样采样率只要 184 秒。两者渲染器和硬件都不同,按书中数字算约为 1428 倍,只能当量级参考。
与 GEA 的对照
| 话题 | GEA4(上文) | PBRT 4e 第 1 章 |
|---|---|---|
| 入门算法 | 眼睛光线 + Blinn-Phong 着色方程 + 阴影光线,再逐步加入透射与随机光线 | 直接对式 1.1 做均匀球面采样的随机游走,从第一天起就是无偏的蒙特卡洛估计 |
| 光线追踪的代价 | 成本高、并行化和缓存友好性差,所以实时引擎多用混合方案(12.5 节) | 从离线生产的角度强调它的好处:单一质量旋钮、渐进预览、阴影不用调参;并认为光栅化渲染器没有同等的渐进能力(1.6.2) |
| 复杂度 | BVH 把 降到 | 同一结论写作 ,并补充构建本身至少 ;脚注强调对数复杂度只是平均情况——不做昂贵预处理时总能构造出 的最坏场景,只是真实场景一般不会这样 |
| 两本书立场不同:GEA 关心每帧 16 ms 的预算,PBRT 关心离线画质与美术效率;"光栅化没有渐进能力"一说只针对离线渲染器,实时引擎中的时间累积(如 TAA)已经是逐帧渐进收敛的做法。 |
原书问题(PBRT 第 1 章,在线版)
| 位置 | 问题 | 核对来源 |
|---|---|---|
| 1.2.6 图 1.11 图注 | 在线版显示未解析的交叉引用 "Section sec:photon-mapping",图注后还多出一行孤立的 "algorithm." | https://pbr-book.org/4ed/Introduction/Photorealistic_Rendering_and_the_Ray-Tracing_Algorithm(本次抓取的 HTML 原文) |
| 1.2.5 | 句子 "The BSSRDF is described in" 在在线版中没有下文 | 同上页面 |
| 1.3.3、1.3.5 | 正文说 Integrator 及其实现定义在 cpu/integrator.h/cpu/integrator.cpp,但表 1.1 和 pbrt-v4 源码中的文件名都是 cpu/integrators.h/cpu/integrators.cpp(不存在 integrator.h) | 表 1.1;https://github.com/mmp/pbrt-v4/tree/master/src/pbrt/cpu (2026-10-13 核对目录列表) |
| 1.4.3 | 声称在线版包含额外内容(另一个相机模型、kd 树、整章双向光传输),但这些内容在线上并不存在 | pbrt-v4 issue #463(https://github.com/mmp/pbrt-v4/issues/463)、pbr-book-website issue #25 |
| 1.2.2 脚注 | 关于光线追踪"对数复杂度只在平均意义上成立"的脚注说 "Szirmay-Kalos and Márton provide pointers to the relevant literature",括号里却引成 (Kelemen and Szirmay-Kalos 2001);参考文献中后者是一篇微表面 BRDF 短文("A microfacet based coupled specular-matte BRDF model with importance sampling"),与光线追踪复杂度无关。应引 Szirmay-Kalos & Márton 1998 "Worst-case versus average case complexity of ray-shooting"(Computing 61(2):103–131,DOI 10.1007/BF02684409,该条目在同书参考文献中也存在) | pbr-book.org/4ed 第 1 章页面脚注与 References 页 HTML;Crossref |
PBRT 的视角:从路径积分推导路径追踪,以及 pbrt 的两个积分器(PBRT 4e 13.2–13.4)
路径追踪由 Kajiya (1986) 在提出 LTE 的同一篇论文中给出,是图形学第一个通用的无偏蒙特卡洛光传输算法;通常每像素要几百到几千个样本。PBRT 从路径积分形式(见 渲染方程 的 PBRT 小节)推导它,以便推广到双向方法。
无穷级数:俄罗斯轮盘赌(13.2.1)
能量守恒使"顶点越多的路径总体上散射的光越少"(单条路径不一定)。先总是估计前几项,再用俄罗斯轮盘赌:以概率 停止,否则剩余各项除以 ,例如 ;推广到每一项都以 停止:。每一项被求值的概率都大于 0 且权重正确,所以无偏。
按面积采样路径为什么不行(13.2.2)
最直接的做法是按面积均匀采样顶点:按面积比选物体 ,再在物体上均匀取点,合起来 ,所有点等概率;最后一个顶点只在发光物体上采样,否则大部分路径为 0。两大问题:相邻顶点多半互相不可见(建筑模型里隔着墙),方差极高;被积函数含 δ 时(点光源、完美镜面)永远采不到非零值,BSDF 越光泽贡献越小。
增量构建路径与下一事件估计(13.2.3)
从相机顶点 出发,每个顶点按 BSDF 采样方向、追踪光线找下一个顶点。这是按立体角采样,而路径积分是对面积,所以要换算
中的大部分因子随之消去;而且追踪光线找到的点必然可见,——可以把光线追踪看作对 中可见性的重要性采样。最后一个顶点单独在光源表面上采样,称下一事件估计 (Next Event Estimation, NEE)。估计器:
长度 的路径复用长度 路径的顶点(光源顶点除外),各项相关但不影响无偏,少追的光线远比相关性重要。第 1 章的 RandomWalkIntegrator 就是 取球面均匀 、只在随机打中发光面时计入 的特例。
SimplePathIntegrator(13.3)
- 与
RandomWalkIntegrator相比 MSE 降 101 倍、耗时 7.8 倍(主要因为随机游走一半方向在不透射表面上直接终止),效率提升 12.8 倍。它的价值在于调试与验证采样代码:开关sampleBSDF(BSDF 采样 / 均匀方向采样)、sampleLights(光源采样 / 只靠打中发光面),足够样本下结果应一致,否则就是采样代码有 bug。光源一律用UniformLightSampler选。 - 路径状态只需当前顶点:路径通量权重 (式 13.8),乘以末端直接光照就是路径贡献。
- 光源按立体角返回样本,所以直接光照估计为 (式 13.9), 是选中该光源的离散概率。先检查 BSDF 是否为零再追阴影光线。
specularBounce:上一次是完美镜面时,光源采样无效,打到的发光面/无限远光源要直接计入;否则它们已经由光源采样算过,再加就重复计数。GetBSDF()返回空 BSDF 表示介质边界(两侧折射率相同、光学上不存在),跳过且不计深度。
PathIntegrator(13.4)
相对 Simple 版的改进:直接光照用 BSDF 采样与光源采样做 MIS;可用任意 LightSampler(如 BVHLightSampler);为 GBufferFilm 初始化首个交点的 VisibleSurface;俄罗斯轮盘赌;可选的路径正则化。书中对比:MSE 降 1.97 倍且快 4.44 倍,效率提升 8.75 倍()。
- 为什么要 MIS:光源采样对小光源、粗糙表面好;BSDF 采样对大光源、光滑表面好(光源样本落进窄高光瓣时分子大、分母小,方差爆炸)。Veach 风格的四块板 × 四个球光源场景显示两者互补,单纯平均两个估计器仍然会被差的那个拖累。估计器为光源样本与 BSDF 样本各一项、各乘 MIS 权重(式 13.10),pbrt 用幂启发式(图 13.10:灯后像素噪声明显少于平衡启发式)。
- 实现结构:光源样本在当前顶点算(
SampleLd());BSDF 样本就是下一条路径光线,若它打中光源,在下一次循环开头乘权重 计入,需要记住上一顶点的 BSDF PDFp_b和几何信息prevIntrCtx。相机光线或完美镜面后打中的光源不加权。δ 光源无法被 BSDF 采样到,直接用式 13.9、不做 MIS。纯镜面 BSDF 跳过光源采样。 allowIncompletePDF=true:因为 BSDF 采样已覆盖所有方向,光源采样分布可以不覆盖低发射方向(即 2.2.3 的 MIS 补偿)。- 工程细节:单面光源背面出现亮点的问题来自交点浮点误差——光源采样参考点若落在发光一侧,背面也会被"照亮";对纯反射或纯透射表面,把参考点挪到出射光线那一侧。即使
LightSampler没返回光源也要消耗两个采样维度,保持各像素样本维度分配一致(8.3 节)。首交点的反照率用 16 个预计算的 Owen 扰乱 Halton 点估计 ,因为降噪器通常先除以反照率,要求它误差小。 - 俄罗斯轮盘赌的设计:终止概率基于路径通量,使存活路径的 约为 1、每条光线贡献相近。要先除掉折射带来的辐亮度缩放(
etaScale):进入 的玻璃时 乘 ,出来又抵消,若据此终止会错杀本该穿出的光线。用各波长rrBeta的最大分量而非平均,避免高饱和反射率下某些分量被放大到超过 1。pbrt 的规则:深度大于 1 且 时取 ,存活则 。表 13.1:Kroken 场景 MSE ×1.31、时间 ×0.261、效率 ×2.92;Watercolor 1.19/0.187/4.51;San Miguel 1.00/0.239/4.17;BMW M6 1.00/0.801/1.25(本页按 复算为 2.92、4.49、4.18、1.25,差异来自表中数值的舍入)。 - 路径正则化 (Path Regularization)(13.4.1):漫反射地面的间接光线偶尔打到镜面车轮再反射到小而亮的太阳,产生萤火虫;车内光线隔着玻璃无法做光源采样,同理。把 BSDF 全部变粗糙能消除尖峰但改变外观;pbrt 只在路径上出现过非镜面散射之后(
anyNonSpecularBounces)才正则化。TrowbridgeReitzDistribution::Regularize():若 ,则 ;漫反射等本已宽的 BxDF 不处理。这是有偏的,但实时路径追踪中常见的"二次反弹后提高粗糙度/限制高光"做法与之同理。 - 延伸阅读中的轮盘赌改进:pbrt 的终止概率主要由上一次散射的反照率决定(Szécsi 等 2003 最早提出);更好的做法还要考虑该点的入射光照——暗处更积极地终止、亮处少终止,Vorba–Křivánek 2016 基于场景光照近似(伴随驱动)设定概率,并在重要区域做路径分裂 (splitting)。
与 GEA 的对照
| 话题 | GEA4(上文) | PBRT 4e |
|---|---|---|
| 推导出发点 | 从渲染方程的递归形式出发:眼睛光线 + 阴影光线 + 递归间接光 | 从路径积分形式出发,路径追踪只是"增量采样顶点 + NEE"的一种路径密度 |
| 直接光照 | 随机选光源方向 | 光源采样与 BSDF 采样 MIS(幂启发式),δ 光源单独处理 |
| 终止 | 俄罗斯轮盘赌(GEA 的补偿写法见 蒙特卡洛积分与重要性采样 的原书问题) | 基于 etaScale 最大分量的轮盘赌,外加 maxDepth 上限 |
原书问题(PBRT 第 13 章)
| 位置 | 原书说法 | 核对结果 |
|---|---|---|
| 13.2.3 | 换算 后," 中除 外的因子都消去" | 按书中同段公式,采样 时 $p_A(p_{i+1})=p_\omega(\omega_i) |
| 第 13 章延伸阅读 | 按反照率设定轮盘赌概率"first introduced by Szesci et al. (2003)" | 同章文献表写作 Szécsi, L., L. Szirmay-Kalos, and C. Kelemen. 2003(WSCG 11(1)),正文拼写有误,应为 Szécsi(笔误) |
PBRT 的视角:回顾与渲染器设计取舍(PBRT 4e 第 16 章)
pbrt 这些年(16.1)
- 路径追踪一直都有,但直到第 3 版才成为默认积分方式;第 1、2 版用大量篇幅讲辐照度缓存等在邻近点复用间接光的技术,如今除光子映射外都已删去,因为采样算法进步、计算机变快,路径追踪及其相关方法成了最合适的重点。
- 代码量:pbrt-v1 约 2 万行,v4 略多于 6 万行(同样不计表格数据与自动生成的解析代码);核心接口(Integrator、Shape、Light、Camera、Filter、Sampler)一直未变。
- 纯算法进步:书中图 16.1(环境光照下的 Audi TT)上,v4 比 v1 慢 1.47 倍,但 MSE 降低 4.42 倍以上,书中给出的净蒙特卡洛效率提升为 3.05 倍(见下方原书问题)。脚注承认这是不精确的比较:v4 改为光谱渲染(v1 用 RGB)、
CoatedDiffuseMaterial等材质需要随机求值、采样算法更好但更费算力、光线求交几何鲁棒性的改进(6.8.8 节)也有性能代价;作者认为结论"方向上成立"。 - 硬件进步:最早在单核 366 MHz Pentium II 笔记本上开发,现在用 32 核 3.7 GHz;1999–2019 年 SPECInt 单线程性能提升 40 倍以上(Rupp 2020),综合估计两台机器相差远超 1,000 倍:当年 1 小时的渲染现在约 3 秒;今天 1 小时的渲染在当年要 42 天。Kajiya 首批路径追踪图像所用的 IBM 4341 浮点性能约 0.2 MFLOPS,Pentium II 约 50 MFLOPS,差 250 倍;GPU 上 pbrt 又比 32 核 CPU 快 10–20 倍,合计约 250 万倍:今天 GPU 上约 10 秒就能完成他的计算机一年的工作(笔者核算:,一年 / s)。
其他设计(16.2)
| 方向 | 做法 | 代表 |
|---|---|---|
| 核外渲染 (out-of-core) | 光线访问不连贯,虚拟内存表现差。先压缩场景:pbrt 存 Figure 7.2 景观场景的 2400 万三角形和 BVH 约 3.3 GB,每个三角形约 148 字节,作者以前的光线追踪器做到约 40 字节(少 3.7 倍),例如按网格顶点数选用 8/16/32 位索引。再按需加载、缓存纹理与几何、重排光线提高缓存一致性 | Peachey 1990、Pharr–Hanrahan 1996、Pharr 等 1997、Christensen 等 2003(简化几何缓存);Disney Hyperion 对大量活跃光线排序(Eisenacher 等 2013、Burley 等 2018) |
| 预着色微多边形网格 | 先把全部几何细分为亚像素三角形,在顶点上求值程序化着色器并存下参数;路径追踪时插值参数直接构造 BSDF,不再求值着色器。交点数多于微多边形数时划算,纹理访问一致、适合 SIMD;缺点是被遮挡的几何白做、启动时间变长 | Weta Manuka(Fascione 等 2018),思路源自 Reyes(Cook 等 1987);Munkberg 等 2016 在渲染中把着色结果缓存到表面纹理 |
| 包追踪与 SIMD | CPU SIMD 宽 8–16 个 float。包追踪让每条 SIMD 通道负责一条光线(Wald 等 2001a),视锥追踪(Reshetov 等 2005);对不连贯光线改为单光线同时测多个包围盒(Christensen 等 2006 等);Embree(Wald 等 2014)两者都支持;或者用 ispc 这类隐式 SPMD 语言(DreamWorks MoonRay,Lee 等 2017);还有完全不用加速结构、递归划分光线与图元的方法(Keller–Wächter 2011、Mora 2011) | pbrt 为避免代码复杂而不使用 SIMD |
| 交互与动画 | 场景到渲染前才确定,需要快速构建或 refit 加速结构、按光线预算出最好的图像,并把降噪深度集成进显示管线;动画可跨帧复用信息 | SVGF(Schied 等 2017/2018)、ReSTIR(Bitterli 等 2020)及其间接光扩展(Ouyang 等 2021) |
| 专门化编译 | OptiX(Parker 等 2010)在运行时把内置功能与用户代码一起编译优化,例如着色从不用 就删掉求交里计算它的代码;Rodent(Pérard-Gayot 等 2019)按场景描述专门化整个渲染器 | 对照 波前路径追踪 中按材质类型生成特化内核 |
- 作者特别建议:即使不做练习,也值得读各章练习,因为凡是 pbrt 做了有争议的取舍的地方,书中都放了一道练习。
- 新兴方向(可微渲染、机器学习)见 可微渲染与神经渲染。作者认为摩尔定律放缓后,采样与渲染算法的创新会越来越重要,GPU 上专用光追硬件让更多实时图形开发者开始使用路径追踪。
- 原书问题(第 16 章参考文献,已用 Crossref 核对):16.2.3 正文引作 "Badouel and Priol 1989",而参考文献列表为 1990(EGGH ’90 工作坊;Springer 文集 1992 年出版,DOI 10.1007/978-3-642-76777-7_8),正文年份与列表不一致;SVGF 论文(Schied 等 2017)第一作者在列表中写成 "Schied, S.",应为 C.(Christoph Schied,DOI 10.1145/3105762.3105770),与 2018 年那篇的 "Schied, C." 一致;Benthin 等 2011 实际刊于 TVCG 18(9)(2012 年 9 月,2011 年在线发表,DOI 10.1109/TVCG.2011.277)。
- 原书问题(存疑):16.1 的效率数字看起来不自洽。蒙特卡洛效率与"MSE × 时间"成反比,按正文的 4.42 与 1.47 算净提升 ,即便两数是四舍五入也最多 ,不到 3.05。但正文说 MSE 改善"超过 4.42 倍",若实际值约 4.48 则 3.05 成立,所以只能算表述不精确。结论"算法进步带来约 3 倍效率提升"不受影响。
取舍
- 与光栅化相比,反射、软阴影、面光源和间接光照在光线追踪框架里自然得到,但成本高、并行化和缓存友好性差(GEA 在 12.5 节引言的说法),所以多数实时引擎用混合方案。
- 路径追踪无偏、统一,但在实时预算下噪点重,最终画质很依赖降噪。
- 双向路径追踪和 MLT 能抓住单向追踪难以找到的光路,代价是实现复杂度。
与 UE5 的对应
UE5 文档把路径追踪器描述为渐进式、硬件加速的无偏渲染模式,用作 ground truth 参考和生产渲染;大部分核心硬件光追功能则集成在 Lumen 里,属于混合渲染(Path Tracer in Unreal Engine、Hardware Ray Tracing in Unreal Engine)。这正对应本页的路径追踪与 GEA 所说的混合引擎,详见 硬件光线追踪与路径追踪器 和 Lumen 全局光照与反射。
原书小问题
- 12.6.5.2 把 BVH 误写成 "BHV"。
出处
- Game_Engine_Architecture_4th_Edtion_Volume_2_-_Jason_Gregory.pdf
- Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 12 章 12.6.3–12.6.5 节
- Path Tracer in Unreal Engine
- Hardware Ray Tracing in Unreal Engine
- PBRT 4e source excerpt: chapter 13 (Light Transport I Surface Reflection)
- Pharr, Jakob, Humphreys《Physically Based Rendering: From Theory to Implementation》第 4 版(MIT Press, 2023)第 13 章 13.2–13.4 节,pbr-book.org/4ed/Light_Transport_I_Surface_Reflection
- PBRT 4e source excerpt: chapter 01 (Introduction)
- Pharr, Jakob, Humphreys《Physically Based Rendering: From Theory to Implementation》第 4 版(MIT Press, 2023)第 1 章 1.2、1.3、1.6 节,pbr-book.org/4ed/Introduction
- PBRT 4e source excerpt: chapter 16 (Retrospective and the Future)
- Pharr, Jakob, Humphreys《Physically Based Rendering: From Theory to Implementation》第 4 版(MIT Press, 2023)第 16 章 16.1–16.2 节,pbr-book.org/4ed/Retrospective_and_the_Future