3、采样策略:蒙特卡洛方法、重要性采样与分层采样

光线追迹的核心,说白了就是解一个高维积分方程。你想想看,每条光线从光源出发,在场景里弹来弹去,最后有多少能量进入相机?这个积分没法直接算,只能靠采样来逼近。

我刚开始做渲染的时候,总觉得采样不就是随机扔光线嘛,有啥技术含量?结果第一次跑室内场景,噪点多得跟雪花似的。后来才明白——采样策略选得好不好,直接决定了你的渲染器是「快且准」还是「慢且糊」。

3.1 蒙特卡洛方法:随机采样的数学根基

蒙特卡洛方法,本质上就是用随机样本来估计期望值。公式很简单:

E[f(x)] ≈ (1/N) * Σ f(x_i) / p(x_i)

其中 p(x_i) 是采样概率密度。这个公式告诉我们:采样点越多,估计越准;但收敛速度只有 O(1/√N)。什么意思呢?想减少一半噪声,你得把采样数翻四倍。

核心洞察:蒙特卡洛的收敛速度是固定的,但我们可以通过改变采样分布来降低方差。方差小了,同样的采样数就能得到更干净的图像。

我在项目中遇到过一个问题:用纯随机采样渲染一个带镜面反射的金属球,噪点怎么都压不下去。后来发现,问题出在采样分布上——大部分光线根本没打到光源方向,白白浪费了计算资源。

3.2 重要性采样:把资源花在刀刃上

重要性采样的思路很直白:对贡献大的区域多采样,贡献小的区域少采样。你想想看,如果场景里有个明亮的窗户,大部分光照都是从窗户进来的,那你何必在暗角浪费那么多光线呢?

具体做法是:让采样概率密度 p(x) 与被积函数 f(x) 的形状尽量接近。理想情况下,p(x) ∝ f(x),方差直接降到零——当然,现实中很难做到完美匹配。

3.2.1 常见的几种重要性采样策略

策略 适用场景 采样分布 我个人的经验
BRDF 重要性采样 漫反射/光泽反射 按 BRDF lobes 分布 漫反射用余弦加权,镜面用 GGX,效果立竿见影
光源重要性采样 直接光照 按光源面积/强度分布 多光源场景一定要做,不然小光源几乎采不到
环境贴图重要性采样 IBL 环境光照 按像素亮度分布 我习惯预计算 CDF,运行时查表,效率很高
多重重要性采样 (MIS) 复杂光照路径 混合多种策略 这是最稳的方案,后面会细讲

避坑指南:我曾经在写 BRDF 采样时,忘了处理采样方向在半球外的情形。结果渲染出来的图像出现奇怪的暗斑,排查了两天才找到原因。记得每次采样后都要检查方向是否有效。

3.3 分层采样:保证空间覆盖均匀

纯随机采样有个毛病:它可能在某些区域扎堆,另一些区域却空着。你想想看,如果像素里的 16 个采样点全挤在左上角,那右下角的信息就全丢了。

分层采样就是来解决这个问题的。把采样空间分成若干个子区域,每个区域里至少采一个点。这样能保证采样点不会「抱团」,空间覆盖更均匀。

3.3.1 分层采样的典型做法

  1. 像素分层:把像素分成 4×4 的网格,每个格子采一个点
  2. 时间分层:运动模糊时,把曝光时间分成 N 段,每段采一个时刻
  3. 半球分层:把方向空间按经纬度分层,每层采一个方向

我记得有一次做动画渲染,运动模糊的噪点特别严重。用了时间分层之后,同样的采样数,画面干净了不止一个档次。说白了,分层采样就是用最小的代价,换取最大的空间均匀性。

3.4 三种策略的对比与选择

这三种策略不是互斥的,实际项目中往往是组合使用。我一般这样选:

场景 推荐策略 理由
漫反射场景,光源单一 分层采样 + 余弦加权 简单高效,实现成本低
镜面/光泽反射为主 BRDF 重要性采样 能大幅降低高光区域的方差
多光源或环境光照 光源重要性采样 + MIS 避免漏掉小光源或亮区域
运动模糊/景深 分层采样 + 重要性采样 既保证时间/空间均匀,又聚焦贡献大的区域
要求极高精度 三者全上 代价是计算量翻倍,但效果最稳

注意:重要性采样不是万能的。如果 p(x) 和 f(x) 的形状差异很大,反而可能放大方差。我见过有人对漫反射场景用了镜面 BRDF 采样,结果噪点比纯随机还严重。选策略之前,先搞清楚你的场景到底「重要」在哪里。

3.5 知识结构总览

下面这张图把三种采样策略的关系和适用场景串起来了,方便你快速回顾:

采样策略知识结构图 采样策略知识结构 采样策略 蒙特卡洛方法 重要性采样 分层采样 随机采样估计期望 收敛速度 O(1/√N) BRDF / 光源 / 环境图 多重重要性采样 (MIS) 像素 / 时间 / 半球分层 保证空间覆盖均匀 组合使用效果最佳 分层采样保证均匀性 + 重要性采样聚焦贡献区域 = 更低的方差,更快的收敛,更干净的图像

3.6 实战建议:如何组合使用

在实际项目中,我很少只用一种策略。这里分享一个我常用的组合套路:

  1. 先分层,再采样——用分层采样保证空间覆盖均匀
  2. 每层内部用重要性采样——在局部区域聚焦贡献大的方向
  3. 最后用 MIS 融合多种策略——避免单一策略的盲区

小技巧:我习惯在调试阶段先关掉重要性采样,只用分层采样跑一遍。这样能快速定位场景中的「热点区域」,然后再针对性地设计重要性采样策略。说白了,先看清问题在哪,再动手优化。

嗯,采样策略这块就聊到这儿。记住一句话:没有最好的采样策略,只有最适合当前场景的采样策略。多试、多调、多对比,慢慢你就能找到手感了。