Chapter 36: Monte Carlo Integration
Monte Carlo Integration 解决 Path Tracing 中的一个核心问题:一个像素的颜色来自大量可能光路的总贡献,渲染器无法穷举全部方向、反弹次数、光源位置、时间、镜头位置和材质随机事件,只能用有限样本估计积分结果。本章用一个贯穿场景展开:一个 diffuse room 里有白墙、粗糙金属球、玻璃球和一盏小面积光。读者读完后应能追踪一次样本从随机数生成、PDF 记录、BRDF 权重、path throughput 更新到帧缓冲累积的完整路径,并据此判断噪声、偏差和采样策略的来源。
Ray Tracing 前几章已经把 primary ray、shadow ray、reflection ray、refraction ray 和递归贡献讲清楚。Monte Carlo Integration 把这些离散路径推广成随机估计:每条路径只提供一次局部观察,多条路径的平均值逼近真实光照积分。路径本身有随机性,估计过程有方差;只要 estimator 的权重、PDF 和采样域一致,样本平均会收敛到目标积分。
本章的主线是从一个命中点的渲染方程出发,建立 sample、PDF、estimator、期望值和方差之间的工程关系。数学公式只服务一件事:解释为什么同样的 sample count 下,不同采样分布会产生完全不同的噪声图案,也解释为什么某些降噪手段会改变能量,形成偏差。
公开版 PBRT 第四版的 Monte Carlo: Basics 给出了 Monte Carlo estimator、PDF 和 variance 的基础推导;Improving Efficiency 进一步解释 stratified sampling、importance sampling 和 multiple importance sampling。本章不复写这些推导,而是把它们放回 Path Tracing 的 frame、shader、buffer 和调试结果中使用。
36.1 Monte Carlo 积分的核心思想与应用场景
在 diffuse room 的墙面命中点上,渲染器要计算沿相机方向离开表面的 radiance。表面反射的简化渲染方程可以写成行内形式:。这里 是命中点, 是朝向相机的出射方向, 是半球上的入射方向, 来自场景中其他表面或光源, 是 BRDF, 是方向与法线夹角产生的投影因子。
这个积分的难点来自采样域。半球方向是连续的,入射光可能来自小光源、墙面反弹、玻璃折射路径或金属高光方向。Path Tracer 每次只抽取少量方向,沿方向追踪下一条 ray,然后把该样本的贡献放大到代表整个采样域。对于任意积分 ,如果从 PDF 抽取样本 ,常用估计量是 。在渲染里, 对应光照、BRDF、几何项、可见性和路径后续贡献的乘积。
Sample 是一次随机选择出来的具体事件。在本章场景中,一个 sample 可以是像素内的一个 subpixel 位置,也可以是墙面命中点上的一条半球方向,还可以是面积光上的一个随机点。PDF 是该事件在对应采样域中的概率密度。对于连续方向,PDF 的单位通常是 solid angle;对于面积光表面,PDF 的单位通常是 area。Estimator 是把样本值和 PDF 合成积分估计的规则。期望值表示重复无限多次随机实验后的平均结果。
Monte Carlo Integration 在渲染中的应用远超反射方向采样。像素抗锯齿会在 pixel footprint 内采样;soft shadow 会在面积光表面采样;depth of field 会在 lens aperture 上采样;motion blur 会在 shutter time 上采样;Path Tracing 会把每次反弹的 BSDF 事件串成高维路径采样。统一的判断规则始终相同:先确认采样域,再确认 PDF 单位,再确认 estimator 中所有贡献项是否与该 PDF 对齐。
对于 diffuse room 的白墙,Lambert BRDF 是常数, 决定斜方向贡献较低。uniform hemisphere sampling 会给半球每个方向相同概率;cosine-weighted sampling 会让接近法线方向的样本更密集。两者都能形成正确 estimator,但后者让样本分布更接近积分中的大贡献区域,所以同样 sample count 下噪声更低。
这条规则也解释了 Path Tracing 的核心工程边界。样本少时,画面有颗粒感;这表示 estimator 的方差已经进入可见范围。PDF 漏记、单位混用、权重写错时,画面会整体变暗、变亮或出现角度相关错误;这属于 biased estimator,继续加样本也会稳定到错误结果。
36.2 样本分布与方差的影响
方差描述多次估计结果围绕真实积分值摆动的程度。对无偏 estimator 来说,样本数 增加时 variance 按 下降,可见误差大致按 下降。这意味着把 64 samples per pixel 提升到 256 samples per pixel,噪声不会按四倍消失;它通常只按平方根速度改善。渲染优化的主要目标因此转向采样分布:让有限样本更频繁落在贡献高的位置。
在 diffuse room 场景中,uniform sampling 的问题是样本覆盖均匀,贡献分布却不均匀。墙面上方的小面积光只占很小方向范围,uniform hemisphere sampling 很少命中它;命中时贡献又很大,于是画面出现亮点和慢收敛阴影。cosine-weighted sampling 解决 diffuse BRDF 与 cosine 项的匹配问题,但它仍然缺少光源位置知识。light sampling 直接在光源上抽点,能显著降低小光源直接光噪声。
BRDF sampling 的目标是匹配材质反射分布。粗糙金属球的高光有明确方向性,uniform sampling 会把大量 ray 发向低贡献方向;按 BRDF 采样时,ray 更集中在镜面瓣附近,反射高光收敛更快。材质越 glossy,BRDF 分布越尖锐,BRDF sampling 的优势越明显。对于纯 diffuse 表面,BRDF sampling 常退化成 cosine-weighted sampling。
不同采样策略解决的是不同因子。渲染方程的 integrand 通常是 ,其中 是可见性。light sampling 匹配 的空间分布,BRDF sampling 匹配 ,cosine-weighted sampling 匹配 。单一策略只能贴近其中一部分。Multiple Importance Sampling(MIS)把多个策略的样本按 PDF 权重合成,核心用途是降低某个策略在低概率高贡献位置产生的极端样本。
| 采样策略 | 采样域 | 适合的场景 | 典型噪声表现 | 主要检查项 |
|---|---|---|---|---|
| Uniform hemisphere | 命中点半球方向 | 调试基线、验证 estimator | 小光源和 glossy 区域噪声高 | PDF 是否为半球 solid angle 常数 |
| Cosine-weighted | 命中点半球方向 | Lambert diffuse 表面 | diffuse 面更平滑,小光源仍慢 | BRDF、cosine、PDF 是否互相抵消 |
| BRDF sampling | BSDF 出射事件 | glossy、metal、rough specular | 高光更稳,直接光可能漏采 | BSDF sample 与 BSDF eval 的 PDF 是否一致 |
| Light sampling | 光源表面或光源方向 | 小面积光、直接阴影 | 直接光更稳,间接 glossy 仍难 | area PDF 与 solid angle PDF 转换是否正确 |
| MIS | 多个采样技术合成 | 小光源加 glossy 材质 | firefly 降低,整体收敛更均衡 | 所有技术的 PDF 是否都按同一采样域评估 |
这个表在调试时可以直接作为判断顺序。先用 uniform sampling 建立基线,确认画面能随 samples per pixel 增加而收敛;再切 cosine-weighted sampling,观察 diffuse 墙面的噪声是否下降;随后开启 light sampling,观察小光源阴影边缘是否稳定;最后对 glossy 球体比较 BRDF sampling 和 MIS。每一步只改一个策略,亮度均值应保持在同一量级,噪声分布应发生可解释变化。
采样分布也受随机数质量影响。相邻像素使用相关随机序列时,噪声会形成条纹、网格或时间闪烁。低差异序列、分层采样和蓝噪声分布都在控制样本的空间分布。它们的共同目标是让样本覆盖更均匀,同时维持 estimator 的权重规则。工程上可以把随机数种子、sample index、pixel coordinate、bounce index 分离混合,减少跨维度相关性。
36.3 在 Path Tracing 中使用 Monte Carlo
Path Tracing 中的 Monte Carlo estimator 以路径为单位工作。一次 camera ray 命中墙面后,shader 评估材质,抽取下一条方向,把当前贡献乘进 path throughput,再继续追踪。Path throughput 是沿路径累计的能量权重,通常包含 BRDF 值、cosine 项、PDF 倒数、材质反射率和 Russian roulette 存活概率的倒数。它表示当前路径后续 radiance 对相机像素的乘法系数。
以下流程图展示一条样本路径如何进入 estimator。图的边界是单个 pixel sample;它不包含 BVH 构建、denoiser 或后处理。
这条路径中有两个常见 estimator。第一个是 next event estimation(NEE):在命中点直接抽取光源点,发 shadow ray 验证可见性,把直接光贡献写入样本颜色。第二个是 BSDF continuation:从 BSDF 分布中抽取下一条 ray,把 throughput 更新后进入下一次反弹。NEE 提高直接光收敛速度,BSDF continuation 保留间接光和 glossy 路径。
简化的 path tracing 循环可以写成如下伪代码。它展示权重的最小结构,省略 BVH、纹理过滤、法线贴图和多光源选择细节。
Vec3 trace_path(Ray ray, RNG& rng) {
Vec3 radiance = Vec3(0.0f);
Vec3 throughput = Vec3(1.0f);
for (int depth = 0; depth < maxDepth; ++depth) {
Hit hit = trace_scene(ray);
if (!hit.valid) {
radiance += throughput * sample_environment(ray.direction);
break;
}
Material mat = hit.material;
radiance += throughput * mat.emission(ray.direction);
DirectSample light_sample = sample_light(hit.position, rng);
if (light_sample.pdf > 0.0f && visible(hit.position, light_sample.position)) {
Vec3 wi = normalize(light_sample.position - hit.position);
float cos_theta = max(dot(hit.normal, wi), 0.0f);
Vec3 brdf = eval_bsdf(mat, -ray.direction, wi, hit.normal);
radiance += throughput * light_sample.radiance * brdf * cos_theta / light_sample.pdf;
}
BsdfSample bsdf_sample = sample_bsdf(mat, -ray.direction, hit.normal, rng);
if (bsdf_sample.pdf <= 0.0f || is_black(bsdf_sample.weight)) {
break;
}
throughput *= bsdf_sample.weight * abs(dot(hit.normal, bsdf_sample.direction)) / bsdf_sample.pdf;
ray = spawn_ray(hit.position, bsdf_sample.direction, hit.normal);
if (depth >= rrStartDepth) {
float survival = clamp(max_component(throughput), 0.05f, 0.95f);
if (rng.next_float() > survival) {
break;
}
throughput /= survival;
}
}
return radiance;
}
这段伪代码有三个关键检查点。第一,直接光和 BSDF continuation 使用了不同采样技术,若开启 MIS,需要把 direct-light sample 和 BSDF sample 都放入同一权重公式中。第二,throughput 每次更新都必须除以当前采样技术的 PDF;漏除会让高概率方向贡献过大,重复除以 PDF 会让画面能量异常。第三,Russian roulette 终止路径后,存活路径要除以 survival probability;这样路径数量下降,期望值保持一致。
Sample accumulation 发生在像素层。每个 pixel sample 返回一个 radiance 估计值,frame buffer 保存平均值:accumulated = accumulated + (sample - accumulated) / sampleCount。累积必须在线性颜色空间进行,最终显示前再做 tone mapping 和 gamma / OETF 编码。把 sRGB 编码后的颜色拿来平均,会让暗部和中间调产生系统性偏差。
在 GPU path tracer 中,上述循环可能写在 ray generation shader、closest hit shader 或 compute shader 中。具体 API 不改变 estimator 规则,但会改变资源组织:随机数状态通常放在 buffer 或纹理中,accumulation target 通常是 HDR texture,材质参数来自 structured buffer 或 descriptor table,路径状态可能在 wavefront path tracer 中被拆成多个 queue。调试时先看 estimator 字段,再看 API 绑定和同步;采样数学正确后,资源错绑才有稳定定位基础。
36.4 常见误区与偏差校正技术
Monte Carlo 渲染的错误可以分成两类:高方差和偏差。高方差表现为噪声随 sample count 增加逐步下降,长时间累积后趋向正确亮度。偏差表现为结果稳定到错误亮度、错误色彩或错误空间分布。排查顺序应先判断亮度均值,再判断噪声形态,最后检查随机数与采样策略。
PDF 漏乘或漏除是最常见的偏差来源。每个 sample 都来自某个采样域,estimator 必须用该域下的 PDF 加权。面积光采样尤其容易出错:如果在光源面积上均匀抽点,初始 PDF 是 area measure;命中点 shading 往往按 direction measure 处理,需要用距离平方和夹角项转换到 solid angle measure。单位未对齐时,靠近光源和远离光源的亮度比例会异常。
颜色空间错误会污染 sample accumulation。Path tracing 的 radiance、throughput、albedo 和 HDR accumulation 都应在线性空间中计算。纹理若以 sRGB 存储,采样后需要转换成线性值再进入 BRDF。最终写屏幕前进行 tone mapping 和显示编码。调试时可以输出一张 linear albedo AOV 和一张 accumulated HDR AOV,确认材质输入和帧缓冲累积没有被同一条 sRGB 曲线重复处理。
随机数相关性会把噪声从细颗粒变成结构化图案。典型症状是墙面上出现固定网格、斜线、低频色块,或者相机静止时噪声在时间上闪烁。稳定做法是把 pixel coordinate、sample index、bounce index 和 dimension index 混合成独立维度,使用同一像素内的 sample sequence 推进路径。可视化 random dimension 或 first-bounce direction 能快速暴露相关性。
Firefly 是极少数样本带来极大贡献的亮点。它常出现在 glossy 材质、小光源、间接 caustics、低 PDF 高 radiance 的路径上。直接 clamp radiance 可以压低 firefly,但会引入 bias,因为 estimator 的高贡献尾部被截断。更稳定的处理顺序是先检查 PDF 单位和 MIS 权重,再增加 light sampling 或 BRDF sampling 的覆盖,随后使用 path throughput 上限或 luminance clamp 作为可控艺术取舍,并记录它改变了能量守恒。
采样不足与 estimator 错误需要分开判断。把 sample count 从 16 提升到 1024 后,如果噪声明显下降且平均亮度稳定,问题主要是方差。若亮度随采样策略切换大幅变化,或高 sample count 后仍偏暗、偏亮、偏色,问题更可能来自 PDF、BRDF eval、颜色空间、法线方向或可见性测试。这个判断优先于主观观察,因为噪声图案很容易掩盖系统性偏差。
Russian roulette 也会形成偏差。路径终止概率如果取决于 throughput,存活路径必须除以 survival probability。若只丢弃路径,不补偿存活路径权重,间接光会偏暗;若 survival 太低,少量存活路径权重过大,firefly 增加。工程上常在若干反弹后启用 Russian roulette,并把 survival 限制在合理范围内,让性能节省和方差增长保持可控。
36.5 采样策略的效果对比
采样策略对比应使用固定场景、固定 sample count、固定曝光和固定随机序列。diffuse room 是合适基线,因为它包含大面积 diffuse 墙、小面积光、glossy 球和玻璃球,可以同时观察直接光、间接光、高光和困难路径。对比时每次只改一项策略,并输出平均亮度、最大样本贡献、PDF heatmap 或 first-bounce direction visualization。
在 diffuse 墙面上,uniform hemisphere sampling 会产生均匀方向覆盖,但墙面主要贡献来自法线附近和可见光源方向。cosine-weighted sampling 会让第一反弹 diffuse 噪声下降,墙面渐变更平滑。若从 uniform 切到 cosine 后整体亮度明显变化,应检查 Lambert BRDF 的 、cosine 项和 PDF 是否配套使用。
在 glossy material 上,BRDF sampling 通常胜过 cosine-weighted sampling。粗糙金属球的反射集中在镜面瓣附近,按 BRDF 分布采样后,高光区域能更快稳定。roughness 降低时,高光分布变窄,错误 PDF 会放大亮点。调试时可以输出 sampled direction 与 perfect reflection direction 的夹角分布,确认采样分布随 roughness 收缩。
在 small light 场景中,light sampling 对直接光贡献最大。小面积光在命中点半球中只占很小 solid angle,BSDF sampling 很少命中光源,阴影和亮斑会长期有噪声。NEE 直接抽光源点后,每个命中点都能估计一次直接光;配合 shadow ray,可见性项变成确定检查。若 NEE 开启后阴影边界有棋盘或漏光,优先检查 shadow ray bias、法线偏移和光源背面判定。
Caustics 是单向 Path Tracing 的困难区域。玻璃球把小光源能量聚焦到地面,贡献来自少量折射路径。相机出发的 BSDF sampling 很难主动命中这些路径,light sampling 也难以穿过正确 specular chain。这个场景的结论是边界判断:Monte Carlo estimator 没有失效,但当前采样技术覆盖高贡献路径的概率极低。工程上可用 bidirectional path tracing、photon mapping、manifold sampling 或 reservoir 技术改善;本章只要求读者能识别这是采样策略覆盖不足,而非简单增加 bounce depth 能稳定解决的问题。
一个可复用的对比流程如下:先锁定曝光、tone mapping 和随机种子;再用 uniform 策略渲染基线;随后分别启用 cosine-weighted、BRDF sampling、light sampling 和 MIS;每一步记录 mean luminance、sample variance、max contribution 和视觉噪声区域。若噪声下降且均值稳定,策略有效。若噪声下降伴随能量明显偏移,应回到 PDF 和 estimator 检查。若均值稳定但 firefly 仍多,应增加覆盖高贡献尾部的采样技术,再考虑有记录的 biased clamp。
最终判断要落到资源与管线。采样策略本身运行在 shader 中,PDF、throughput、radiance、random state 和 accumulation target 是可观察对象。RenderDoc 或 API debugger 能检查 texture / buffer 绑定、HDR render target 格式和 shader 常量;自定义 AOV 能检查 per-sample PDF、throughput 和 first-bounce direction。工具回答的是“数据是否按预期进入 shader”,采样对比回答的是“estimator 是否按预期收敛”。两者结合,才能把噪声问题从画面感受转成工程证据。
最小自检任务
给定一个简化 Path Tracer:场景是一个白色 diffuse room,天花板上有一盏很小的面积光,地面有一个粗糙金属球。你可以在四种模式中切换:uniform hemisphere sampling、cosine-weighted sampling、BRDF sampling、light sampling。所有模式使用相同 sample count、相同曝光、相同线性 HDR accumulation。请判断每种模式最可能改善哪一类噪声;如果 uniform 与 cosine-weighted 的平均亮度不同,应优先检查哪些项;如果 light sampling 开启后直接阴影稳定但金属高光仍有 firefly,应如何继续排查。
答案要点
uniform hemisphere sampling 主要作为基线,用来确认 estimator 会随 sample count 收敛。cosine-weighted sampling 最先改善 diffuse 墙面和地面的第一反弹噪声,因为它匹配 Lambert 积分中的 cosine 项。BRDF sampling 更适合粗糙金属球的 glossy 高光,因为它把更多 ray 发向高反射方向。light sampling 最直接改善小面积光带来的直接照明和阴影噪声,因为它让每个命中点都能主动估计一次光源贡献。
uniform 与 cosine-weighted 的平均亮度不同,优先检查 Lambert BRDF 的 、cosine 项、cosine-weighted PDF 、法线方向和 hemisphere 采样域。两种策略的噪声形态可以不同,长期平均亮度应一致。若亮度不一致,问题更可能是 estimator 权重或 PDF 单位错误。
light sampling 开启后直接阴影稳定但金属高光仍有 firefly,说明直接光可见性估计已经改善,高贡献尾部更可能来自 glossy BRDF 路径、低 PDF 样本或 MIS 权重缺失。排查顺序是输出 BSDF PDF、light PDF、throughput 和最大样本贡献;随后确认 BRDF sampling 与 light sampling 是否使用同一 measure 进入 MIS;最后把 clamp 作为带偏差的艺术控制,并记录阈值对平均能量的影响。
本章知识点总结
- 积分目标:Path Tracing 用有限随机样本估计渲染方程中的高维光照积分。
- 样本含义:Sample 是一次具体随机事件,可以来自像素、方向、光源、时间或镜头采样域。
- PDF 角色:PDF 描述样本在对应采样域中的概率密度,并决定 estimator 的权重分母。
- 估计规则:Monte Carlo estimator 通过样本贡献除以 PDF,再对多次样本求平均来逼近积分。
- 方差来源:噪声来自有限样本的随机摆动,样本数增加时可见误差通常按平方根速度下降。
- 分布匹配:采样分布越贴近 integrand 的高贡献区域,同样 sample count 下方差越低。
- 策略边界:cosine-weighted 匹配 diffuse cosine 项,BRDF sampling 匹配材质反射瓣,light sampling 匹配直接光分布。
- MIS 作用:MIS 把多个采样技术按 PDF 权重合成,用来降低单一策略在低概率高贡献位置的极端样本。
- Throughput:Path throughput 累计 BRDF、cosine、PDF、反射率和路径存活概率,表示后续 radiance 对像素的乘法权重。
- NEE 路径:Next event estimation 在命中点直接抽取光源并发 shadow ray,主要改善小光源直接光噪声。
- 偏差判断:高 sample count 后仍稳定偏亮、偏暗或偏色,通常应检查 PDF、颜色空间、法线和可见性。
- 颜色累积:Radiance 与 accumulation target 应使用线性空间,显示编码应放在 tone mapping 之后。
- Firefly 处理:Firefly 优先通过 PDF 校验、MIS 和更合适采样策略处理,clamp 属于带偏差的可控取舍。
- 对比流程:采样策略对比应固定场景、sample count、曝光和随机种子,每次只改变一个采样变量。
- 工具证据:AOV、frame capture 和 API debugger 分别帮助观察 PDF、throughput、资源绑定和 HDR 累积状态。