覆盖:空间滤波 · 时域抗锯齿 · 学习型降噪 · 离线渲染降噪
参考课程:GAMES202 实时高质量渲染
1. 噪声的本质与降噪分类
1.1 噪声来源
实时/离线渲染中的噪声本质上来自 Monte Carlo 积分的方差:
当
降噪的本质:在保留高频信号(边缘、细节)的前提下,对渲染结果进行低通滤波,等效于增大等效采样数
1.2 降噪策略分类
1 | |
1.3 关键指标
| 指标 | 说明 |
|---|---|
| PSNR(峰值信噪比) | |
| SSIM(结构相似度) | 感知质量度量,0~1,越接近 1 越好 |
| 时域稳定性 | 相邻帧间闪烁量,工程上常用帧差分方差衡量 |
| 延迟 | 滤波在帧时间中的占比,实时要求通常 <2 ms(4K/60fps) |
2. 空间滤波
2.1 高斯模糊与双边滤波
高斯模糊(基线)
其中
缺陷:对所有邻域像素一视同仁,导致边缘被模糊。
双边滤波(Bilateral Filter)
在空间核的基础上,增加值域核(Range Kernel),感知像素值的相似度:
直觉:只要你”离我近”且“长得像我”,我才受你影响。颜色突变处
Joint Bilateral Filter(联合双边滤波):值域核不使用被滤波图本身,而是使用辅助的 G-Buffer(法线、深度等):
工程注意:对于直接光照和间接光照应分离滤波,再合并,可避免高频直接光照过度平滑。
2.2 Edge-Avoiding À-Trous 小波变换
核心思想
À-Trous(法语”带孔”):在 5×5 卷积核的偏移中乘以步长 step,以 25 次固定采样覆盖更大半径,不同 Pass 中 step 指数增长:
| Pass | step | 等效覆盖半径 |
|---|---|---|
| 0 | 1 | 2 px |
| 1 | 2 | 4 px |
| 2 | 4 | 8 px |
| 3 | 8 | 16 px |
| 4 | 16 | 32 px |
5 个 Pass 共 125 次采样,等效于半径 32px 的暴力滤波(需
B3-Spline 卷积核
标准的 À-Trous 核使用 B3-Spline,是对高斯的近似:
1 | |
所有权重之和 = 1.0(归一化)。
联合权重公式
:颜色敏感度,越小越保守(越容易判定为边缘)。 :法线敏感度,建议 。 :深度敏感度,需按深度范围归一化。
完整 GLSL 实现(单 Pass)
1 | |
工程要点
- 深度权重使用梯度感知归一化(
zVar),防止斜面(grazing angle)上的假边缘。- 多 Pass 之间 Ping-Pong FBO,上一 Pass 输出作为下一 Pass 的颜色输入。
u_SigmaC应随画面亮度动态调整(HDR 场景中高亮区域方差更大)。
2.3 SVGF(Spatiotemporal Variance-Guided Filtering)
论文:Schied et al., Spatiotemporal Variance-Guided Filtering, HPG 2017
SVGF 是目前实时光追降噪的工业标准基线,它在 À-Trous 的基础上增加了两个关键模块:时域积累 和 方差引导。
完整管线
1 | |
方差引导的关键公式
SVGF 中,颜色权重的
:时空积累得到的局部方差(经过空间平滑后更稳定)。 :调节灵敏度的超参数(论文建议 )。 :防止除零的小量(如 )。
直觉:高方差区域(噪点多)允许更大的颜色差异被视为”同类”,从而加强平滑;低方差区域(已收敛)则收紧阈值,保留细节。
时域积累(Temporal Accumulation)
1 | |
常见问题:
alpha = 0.1意味着 EMA 等效约 10 帧,过小(如 0.01)导致 ghosting,过大(如 0.5)导致时域噪点残留。实践中可根据运动向量长度动态调整。
3. 时域抗锯齿与历史帧复用
3.1 TAA(Temporal Anti-Aliasing)原理
TAA 本质是将多帧 jitter 采样在时间轴上积累,等效于超采样(MSAA/SSAA)但无额外的帧内开销。
Jitter 策略:每帧在亚像素范围内偏移投影矩阵:
1 | |
Halton 序列的前 8 个样本(基数 2 和 3):
| 帧 | ||
|---|---|---|
| 0 | 0.500 | 0.333 |
| 1 | 0.250 | 0.667 |
| 2 | 0.750 | 0.111 |
| 3 | 0.125 | 0.444 |
| 4 | 0.625 | 0.778 |
| 5 | 0.375 | 0.222 |
| 6 | 0.875 | 0.556 |
| 7 | 0.062 | 0.889 |
3.2 历史帧混合与 Resolve
1 | |
3.3 Ghost / Disocclusion 问题与对策
| 问题 | 原因 | 对策 |
|---|---|---|
| Ghosting(鬼影) | 历史帧数据已过时但仍混入 | Variance Clipping / Color AABB Clamping |
| Disocclusion(去遮挡) | 物体移开后露出背景,历史帧无有效数据 | 深度/法线检测 + 快速重置 alpha |
| Aliased History(历史锯齿) | 双线性插值历史帧引入新锯齿 | Catmull-Rom 5-tap 重采样 |
| Flickering(闪烁) | Variance Clipping 过激 | 动态调整 gamma,运动向量越大 gamma 越大 |
Catmull-Rom 5-tap 历史帧采样(比双线性更锐利,无新锯齿):
1 | |
4. 基于学习的降噪
4.1 OIDN(Intel Open Image Denoise)
OIDN 是基于预训练 CNN 的离线/半实时降噪库,可在 CPU/GPU 上运行。
网络架构:改进的 U-Net,输入为 HDR 颜色 + 辅助 G-Buffer(法线、反射率)。
1 | |
C++ 集成示例:
1 | |
工程注意
- 输入颜色必须是线性 HDR(Gamma 空间会导致颜色偏移)。
cleanAux = false意味着法线/反射率也需降噪(推荐单独先 denoise auxiliary buffers)。- 首次
execute较慢(JIT 编译),生产环境建议预热。
4.2 NRD(NVIDIA Real-time Denoise)
NRD 是针对实时渲染设计的降噪框架,核心思想是将噪声数据拆解为低方差的辐照度估计 + 高频的材质反射率,分别降噪后重组。
信号分解:
降噪只作用于
主要降噪器:
| 降噪器 | 适用信号 | 特点 |
|---|---|---|
REBLUR |
漫反射 GI / 镜面反射 | 时空自适应模糊,主力方案 |
RELAX |
漫反射 GI(Lumen 使用) | 基于 SVGF 扩展,对漫反射效果更好 |
SIGMA |
阴影(硬/软) | 专用阴影降噪,避免漏光 |
REFERENCE |
调试用 | 无降噪,直接输出积累均值 |
REBLUR 核心思路(简化):
1 | |
NRD SDK 集成要点(Vulkan/D3D12):
1 | |
4.3 神经网络降噪原理
训练数据构成
| 输入 | 说明 |
|---|---|
| Noisy Image(1~16 SPP) | 带噪声的低采样渲染 |
| Reference Image(4096 SPP) | Ground Truth |
| G-Buffer(法线/反射率/深度) | 结构辅助信息 |
损失函数
简单 L1/L2 损失会偏好模糊,感知质量差。工业实践常用:
推理加速技巧
- FP16 量化:权重和激活使用 16-bit 浮点,速度 2×,质量损失极小。
- TensorRT 优化:算子融合 + Kernel 自动调优,RTX GPU 上可达实时(<2 ms)。
- 滑动窗口推理:对 4K 分辨率分 Tile 推理,控制显存占用。
- 知识蒸馏:用大模型训练小模型,以 90% 的质量换取 5× 的速度。
5. 离线渲染降噪
5.1 Monte Carlo 噪声特性
离线渲染(电影/产品级)的 Monte Carlo 积分噪声具有以下特点:
- 高动态范围(HDR):直接光 firefly 可达正常像素亮度的
倍以上。 - 结构性噪声:噪声分布受 BSDF、光源分布影响,不是均匀白噪声。
- 路径长度相关:间接光照噪声远大于直接光照。
5.2 方差缩减技术(Variance Reduction)
这些技术在采样阶段减少噪声,是降噪的前置优化。
重要性采样(Importance Sampling)
按被积函数形状分配采样密度:
实践中的应用:
- BRDF 采样:按 GGX/Beckmann lobe 形状采样
。 - 光源采样(Next Event Estimation):直接采样光源,避免大量无贡献路径。
- MIS(Multiple Importance Sampling):结合 BRDF 和光源采样,取长补短:
低差异序列(Quasi-Monte Carlo)
用 Halton、Sobol 等低差异序列替代随机采样,同等采样数下方差更低:
1 | |
俄罗斯轮盘(Russian Roulette)
以概率
1 | |
5.3 OptiX AI Denoiser
NVIDIA OptiX 内置的 AI 降噪器,用于离线渲染后处理。
特点:
- 训练于海量电影级渲染数据。
- 支持 AOV(Arbitrary Output Variables):法线、反射率、深度单独输入。
- 支持时域模式(需提供运动向量),大幅减少闪烁。
- 支持 HDR 输入,火萤抑制能力强。
OptiX 7 集成示例:
1 | |
6. 横向对比与选型指南
算法特性对比
| 算法 | 类型 | 帧延迟 | 时域稳定性 | 边缘质量 | 工程难度 | 适用场景 |
|---|---|---|---|---|---|---|
| Bilateral Filter | 空间 | 极低 | ✗(单帧) | ★★★ | 低 | 轻量后处理、原型验证 |
| À-Trous(单帧) | 空间 | 低 | ✗ | ★★★★ | 低 | 无历史帧场景(如截图工具) |
| SVGF | 时空 | 低 | ★★★ | ★★★★ | 中 | 实时光追基线 |
| TAA | 时域 | 低 | ★★★★ | ★★★ | 中 | 抗锯齿标配,配合其他降噪使用 |
| NRD (REBLUR) | 时空 | 低 | ★★★★★ | ★★★★★ | 高 | AAA 游戏实时光追 |
| OIDN | 学习型 | 高(数十ms) | ★★(需配合TAA) | ★★★★★ | 低 | 离线渲染、工具链 |
| OptiX Denoiser | 学习型 | 高 | ★★★★ | ★★★★★ | 中 | 离线渲染(NVIDIA GPU) |
选型决策树
1 | |
常见调参经验
1 | |
7. 参考文献
核心论文
| 论文 | 会议/年份 | 关键贡献 |
|---|---|---|
| Tomasi & Manduchi, Bilateral Filtering for Gray and Color Images | ICCV 1998 | 双边滤波原型 |
| Dammertz et al., Edge-Avoiding À-Trous Wavelet Transform for Fast Global Illumination Filtering | HPG 2010 | À-Trous 降噪 |
| Schied et al., Spatiotemporal Variance-Guided Filtering | HPG 2017 | SVGF |
| Chaitanya et al., Interactive Reconstruction of Monte Carlo Image Sequences using a Recurrent Denoising Autoencoder | SIGGRAPH 2017 | 循环神经降噪 |
| Bako et al., Kernel-Predicting Convolutional Networks for Denoising Monte Carlo Renderings | SIGGRAPH 2017 | KPCN |
| Schied et al., Gradient Estimation for Real-Time Adaptive Temporal Filtering | SIGGRAPH Asia 2018 | SVGF 梯度扩展 |
| Liu et al., NRD: NVIDIA Real-time Denoiser | GDC 2021 | NRD 工业实现 |
学习资源
- GAMES202:闫令琪,实时高质量渲染,Lecture 10~12(降噪专题)
- Shadertoy À-Trous 实现:https://www.shadertoy.com/view/ldKBzG
- NRD SDK:https://github.com/NVIDIAGameWorks/RayTracingDenoiser
- OIDN 文档:https://www.openimagedenoise.org/documentation.html
- OptiX 文档:https://raytracing-docs.nvidia.com/optix8/guide/
⚡ 速览层
用于快速回忆核心概念。每个算法一张卡片,深入内容见对应章节。
🧠 一句话理解噪声
渲染噪声 = Monte Carlo 积分的方差。每像素采样数
降噪的本质 = 在保留边缘的前提下做低通滤波,等效增大
📇 算法速查卡
🔷 Bilateral Filter(双边滤波)
| 本质 | 高斯模糊 × 值域相似度权重,相似才参与平均 |
| 公式核心 | |
| 解决什么 | 普通模糊糊掉边缘的问题 |
| 局限 | 单帧,无时域信息;大核性能差 |
| 适用 | 轻量后处理、原型验证 |
| 深入 | → 2.1 节 |
🔷 À-Trous 小波变换
| 本质 | 带孔卷积 = 固定 25 次采样,步长指数增大,覆盖大半径 |
| 关键数字 | 5 Pass × 25 采样 = 等效 32px 半径,效率约普通模糊的 33× |
| 权重构成 | |
| 解决什么 | 在 À-Trous 大半径滤波中保留几何/纹理边缘 |
| 局限 | 单帧;无法自适应方差;σ 参数需手动调 |
| 适用 | 无历史帧场景、SVGF 的空间滤波模块 |
| 深入 | → 2.2 节 |
🔷 SVGF(时空方差引导滤波)
| 本质 | À-Trous + 时域积累 + 方差自动驱动滤波强度 |
| 管线 | 时域积累 → 方差空间平滑 → À-Trous(5 Pass) |
| 关键公式 | $w_c = \exp!\left(-\frac{ |
| 解决什么 | À-Trous 单帧噪点残留 + σ 参数难调问题 |
| 局限 | 高速运动场景历史帧失效;间接光时域不稳定 |
| 适用 | 实时光追降噪基线(自研首选) |
| 深入 | → 2.3 节 |
🔷 TAA(时域抗锯齿)
| 本质 | 每帧亚像素 Jitter,历史帧 EMA 积累 = 时域超采样 |
| 关键操作 | 重投影(运动向量)→ Variance Clipping → EMA 混合 |
| Jitter 推荐 | Halton(2,3) 序列,8 帧循环 |
| 解决什么 | 锯齿 + 低采样噪声,零帧内开销 |
| 局限 | 运动/遮挡边缘 ghosting;需要正确的运动向量 |
| 适用 | 几乎所有实时渲染管线的标配组件 |
| 深入 | → 3 节 |
🔷 NRD / REBLUR(NVIDIA 实时降噪)
| 本质 | 信号分解(反射率 × 辐照度)+ 自适应半径时空模糊 |
| 核心思路 | 只对低频辐照度 |
| 自适应半径 | |
| 解决什么 | SVGF 在镜面/光泽材质和高速运动场景的质量不足 |
| 局限 | 集成复杂(需 Vulkan/D3D12);调参成本高 |
| 适用 | AAA 游戏实时光追(工业标准) |
| 深入 | → 4.2 节 |
🔷 OIDN(Intel 开放图像降噪)
| 本质 | 预训练 U-Net CNN,输入噪声图 + G-Buffer,直接输出干净图 |
| 输入 | color(必须)+ albedo + normal(可选但推荐) |
| 要求 | 输入必须是线性 HDR,非 Gamma 空间 |
| 解决什么 | 离线渲染场景的一键高质量降噪,无需手调参数 |
| 局限 | 延迟数十 ms,时域稳定性差(需配合 TAA) |
| 适用 | 离线渲染工具链、截图/烘焙工具 |
| 深入 | → 4.1 节 |
🔷 OptiX AI Denoiser
| 本质 | NVIDIA GPU 专用预训练降噪器,集成于 OptiX 渲染框架 |
| 优势 | 支持 AOV 辅助 + 时域模式(运动向量)+ 强 firefly 抑制 |
| 限制 | 仅 NVIDIA GPU;需 CUDA/OptiX 环境 |
| 适用 | 电影/产品级离线渲染(NVIDIA 生态) |
| 深入 | → 5.3 节 |
🗺️ 30 秒选型
1 | |
🔑 三个最重要的概念
- Joint Bilateral:用法线/深度辅助判断边缘,比单纯颜色双边滤波准确得多。G-Buffer 是降噪质量的天花板。
- 方差引导(SVGF 核心):噪点多的地方大力模糊,已收敛的地方轻触,σ 不是常数而是实时估计的方差。
- 信号分解(NRD 核心):
,反射率高频从 G-Buffer 精确获取,只对低频辐照度做降噪,任务难度大幅降低。
⚠️ 工程常见坑
| 坑 | 症状 | 解法 |
|---|---|---|
| σ 过小 | 降噪不足,噪点残留 | 增大 c_phi,或开启方差引导 |
| σ 过大 | 过模糊,边缘丢失 | 减小 c_phi,增加法线/深度权重 |
| TAA ghosting | 运动物体有拖影 | 检查运动向量精度;加强 Variance Clipping |
| 历史帧闪烁 | 画面抖动 | 提高历史帧权重(降低 blend alpha) |
| HDR firefly | 亮点爆炸 | À-Trous 前做 clamp;或用 NRD Anti-firefly |
| OIDN 颜色偏移 | 降噪后色调偏暖/偏冷 | 确认输入为线性空间,非 sRGB |
| 深度边缘误判 | 斜面上出现假边缘 | À-Trous 深度权重加梯度感知归一化 |