Rendering Lecture 8:Path Tracing II

Course: 渲染基础 Rendering Basics Date: November 29, 2025 11:07 AM (GMT+8)

🎨 Rendering Lecture 8:Path Tracing II


🏛 1. 本节主题概览

本节主要围绕路径追踪中的后期环节展开,内容包括:

  • 🌈 过滤(Filtering / Reconstruction)
  • 🚀 并行化(Parallelization)
  • 📊 误差度量与统计特性(Error & Variance)
  • 🎚 后处理(Post-processing:Tone Mapping & Gamma)

这些部分共同解决渲染中实际出现的:

  • 锯齿(aliasing)
  • 噪声(variance)
  • 大范围亮度压缩
  • 性能并行化问题

🌈 2. Filtering:解决 aliasing 的关键步骤

过滤操作发生在 图像坐标空间,目标是:

  • 减少采样不足导致的 aliasing
  • 平滑高频区域
  • 改善像素重建质量

对比图中:

  • 左侧使用过滤 → 高频区域无亮点噪声
  • 右侧未过滤 → 明显的高频亮点

说明过滤能有效降低“采样点落在高频函数上导致的不稳定高值”。


🖥 3. 像素采样与重建的抽象模型

为了更直观解释过滤:

将屏幕视为一维 f(x) 函数采样:

  • f(x):光传输积分的结果(每个像素的真实亮度)
  • 屏幕只能存离散值 → 类似音频采样 → 容易 aliasing
  • 采样频率太低 → 无法恢复原始信号
  • 超过 Nyquist frequency 时 → aliasing 产生

为了避免 aliasing,有两种方式:

  1. 增加采样频率(更高分辨率,但不可行)
  2. 应用 低通滤波器(low-pass filter)

本节的核心就是第 2 种:对 f 进行卷积以限制其高频部分。


🧰 4. 卷积过滤(Convolution Filtering)

目标:得到 平滑后的 f ⊗ H(H 为卷积核)。

  • 积分为 1(不改变平均亮度)
  • 支持大小合适(太小无效,太大会模糊)
  • 形状需合理(不同核带来不同 artifact)
  • Box Filter(盒式):最简单,但泄露高频
  • Tent Filter(锥形):稍好
  • Gaussian(高斯):表现优秀,但会变模糊
  • Mitchell–Netravali:可产生锐化效果,但有 ringing

📐 5. 卷积在渲染中的实际计算方式

实际无法直接得到 f(x),只能得到样本值:

  • 在卷积核覆盖范围内
  • 每个样本的贡献按核权重计算
  • 权重求和需要归一化(减少噪声)

公式包含:

numerator=f(sample)H(offset)denominator=H(offset)pixel_value=numeratordenominator \text{numerator} = \sum f(\text{sample}) \cdot H(\text{offset}) \\ \text{denominator} = \sum H(\text{offset}) \\ \text{pixel\_value} = \frac{\text{numerator}}{\text{denominator}}

核大于一个像素 → 样本会影响多个像素。


🔀 6. Filter Separable 性质(可分离过滤)

大部分常见滤波器是 可分离的

2D filter=1D_filter1D_filter \text{2D\ filter} = \text{1D\_filter} \otimes \text{1D\_filter}

优势:

  • 只需保存 1D 核
  • 计算量从 O(n²) 降到 O(n)

在实际渲染器实现中非常重要。


🚀 7. Parallelization:如何并行化 Path Tracing

路径追踪本质是 embarrassingly parallel:

  • 每条路径独立
  • 不同像素独立

不为“每个样本、每个像素”开线程(太多 overhead), 通常采用 block-based tiling

  • 图像被划分为 2×2、4×4 或更大块
  • 每个 block 分派给线程
  • block 边缘需要额外 padding(因为过滤核跨像素)
  • 各 block 的 numerator、denominator 必须先求和
  • 整张图像合并后才做除法

因此必须存储:

  • per-pixel numerator(RGB)
  • per-pixel filter weight(第四通道)

最终:

final_pixel=numeratorweight_sum \text{final\_pixel} = \frac{\text{numerator}}{\text{weight\_sum}}

渲染系统(例如 Nori)使用 4 通道向量存储这些内容。


🖥 8. 多机器分布式渲染

方式:

  • 使用不同随机种子生成多张图
  • 用 32-bit float 图像逐像素累加
  • 最后求平均

这使得集群渲染具备线性扩展性。


📊 9. Measuring Error:误差度量与统计特性

路径追踪结果是估计值,因此必然存在:

  • 误差(error)
  • 方差(variance)
  • 标准差(standard deviation)
  • 绝对误差

    error_abs=IestItrue \text{error\_abs} = I_{\text{est}} - I_{\text{true}}
  • 相对误差

    error_rel=IestItrueItrue \text{error\_rel} = \frac{I_{\text{est}} - I_{\text{true}}}{I_{\text{true}}}

使用以下方式防止正负误差抵消:

  • |error|
  • error²
  • RMSE、MSE

🧪 10. Unbiased / Biased Estimators 行为

  • 期望值 = 真值
  • 误差围绕 0 上下波动
  • 随着样本数增加 → 波动范围变小
  • 期望 ≠ 真值
  • 样本数增加时 → 仍能收敛到真值
  • 如:一些粗略近似模型
  • 永远不收敛,例如:

    • 过度 clamping
    • 忽略焦散
    • 省略 recursion depth

📉 11. 方差分布与误差分布

路径追踪中的 Monte Carlo 估计量:

  • 服从中心极限定理
  • 收敛到正态分布
  • 方差决定结果离散程度
  • 方差 ∝ 1/N(N 为样本数)

因此:

双倍样本方差减半 \text{双倍样本} \rightarrow \text{方差减半}

📈 12. 方差估计与标准差(噪声图)

无需知道 ground truth:

  • 直接根据样本 f/p 的离散度
  • 用 Welford 算法在线更新方差
  • 得到 per-pixel variance map

标准差图能直观看到:

  • 哪些区域噪声大
  • 焦散等亮度变化极端处 variance 大

📌 13. Adaptive Sampling(自适应采样)

基于 variance map:

  • 给噪声大的区域更多采样
  • 给噪声少的区域减少采样

提高整体效率。


🧼 14. Denoising(基于方差的平滑)

噪声高的区域可以:

  • 进行更多平滑
  • 但平滑算法通常有偏
  • 在图像质量与物理正确性间权衡

📊 15. 算法比较:如何公平评判渲染策略?

常用指标:

  • MSE(均方误差)
  • Relative MSE
  • MAE(绝对误差均值)
  • RMSE
  • 也可使用 variance map 的平均值(更稳健)

特别注意:

  • Fireflies(极值噪声)会严重破坏 MSE 指标
  • 因此作者建议使用 均方方差的平方根(更平滑)

🎚 16. 后处理:Tone Mapping(色调映射)

现实光照的动态范围:

  • 阳光 vs 月光差异可达 8000 万倍
  • 人眼适应能力 ≈ 1 亿动态范围
  • 显示器通常只有 1000:1
  • 普通图像格式只有 8-bit / channel(256 levels)

因此需要:

  • 把 HDR 渲染结果 → 压缩到 0–1
  • 除以最大亮度
  • Clamp 到 [0,1]
  • Log 映射

但这些都不稳定、难以控制。


🌟 17. Reinhard Tone Mapping

最经典广泛使用的方法。

  • 全局版本:所有像素使用同一函数
  • 局部版本:根据每个像素邻域自适应调节参数
  • 局部版本更清晰、能保留细节(不模糊边缘)

效果比较:

  • 局部版在亮点与暗部保留更多细节
  • 全局版更容易“雾化”高频结构

🎨 18. Gamma Encoding(伽马编码)

人眼对亮度的感知是非线性的:

  • 对暗部更敏感
  • 对亮部不敏感

因此:

  • 保存/传输图像时进行 gamma 编码
  • 渲染计算保持线性空间
  • 读取贴图时要 gamma decode

常用公式:

image_out=image_linear1/2.2 \text{image\_out} = \text{image\_linear}^{1/2.2}

通常在 Tone Mapping 之后 做 Gamma。


📌 19. HDR 格式无需 Tone Mapping 或 Gamma

HDR(16–32 bit float)格式本身即可:

  • 存储极大范围亮度
  • 不需要压缩
  • 不需要 gamma

但显示时仍需 tone map。


🧾 20. 小结

本节完整覆盖:

  • 🌈 Filtering:解决 aliasing
  • 🚀 Parallelization:Block-based 并行处理
  • 📊 Error & Variance:统计属性、方差估计
  • 🔍 Adaptive Sampling / Denoising
  • 🎚 Tone Mapping(Reinhard)
  • 📈 Gamma Encoding

这些部分构成路径追踪从物理求解到视觉呈现的完整下半段链路。