跳转到内容

Cook 1986 — 用噪声换掉锯齿

是什么

Cook 1986 提出:渲染图像时故意把规则的采样位置打乱,让本来会出现的”锯齿/摩尔纹”变成肉眼看不太见的”颗粒噪点”。

日常类比:拍格栅栏。

  • 如果你等距地一格一格按下快门,照片上会出现奇怪的条纹(摩尔纹)——这就是 aliasing
  • 如果你抖一下相机再拍,得到的是轻微毛刺——这是 noise
  • 人眼对毛刺很宽容,对条纹特别敏感

stochastic sampling 就是把第一种错误(眼睛敏感)转成第二种错误(眼睛宽容)。

为什么重要

不理解 stochastic sampling,下面这些事都没法解释:

  • 为什么 Pixar 的 RenderMan 在 1986 年就能渲出没有锯齿、有自然运动模糊的电影画面
  • 为什么离线渲染至今还在用 jittered / Poisson disk 这两个 1986 年的采样模式
  • 为什么 Monte Carlo path tracing 一定要”随机”——不是为了”模拟物理”,是为了”骗过眼睛”
  • 为什么游戏引擎做 TAA 也要把每帧采样位置抖一下

核心要点

Cook 论文的核心可以拆成 三层

  1. 诊断:规则采样(每像素中心一个样本)会把高频信号”折叠”成低频假信号——这就是 aliasing。数学上叫 Nyquist 极限:采样频率 < 信号频率两倍时必出错。

  2. 关键洞察:信号本身没法降低频率(场景就是那么细),但错误的样子可以换。把”等距采样”换成”非均匀采样”,能量从”几个高峰”散成”宽频底噪”。

  3. 两种实现

    • Poisson disk:随机撒点,但任意两点间距离 ≥ r。模仿视网膜光感受器排布(Yellott 1982/83)。质量好,但生成慢。
    • Jittered:把像素切成 N×N 子格,每子格随机放一个样本。质量略差于 Poisson disk,但几乎免费。Pixar 用的就是这个。

实践案例

案例 1:抗锯齿对比(最直观)

一张高频条纹纹理,正前方拍:

  • 规则采样:屏幕上出现完全不存在的粗条纹(aliasing)
  • jittered 采样:高频部分变成沙粒状颗粒,主体清晰

人眼几乎察觉不到颗粒,但条纹一眼就看见。Cook 用这个对比一锤定音。

案例 2:运动模糊(多维抖动的威力)

电影里飞过的子弹应该有拖影。传统做法是渲多帧再叠加——慢且依然有锯齿。

Cook 的做法:

  1. 给每个样本分配一个时间值 t ∈ [0, 1](在快门打开期间随机)
  2. 渲染那一时刻的场景
  3. 同一像素内多个样本对应的是不同时刻的子弹位置

聚合后自然得到拖影,没有任何额外帧

景深、软阴影、glossy 反射全是同一招——把”不知道怎么积分的维度”丢给随机采样。

案例 3:游戏 TAA(同思想,跨 30 年)

UE4 的 Temporal AA:每帧把样本位置在像素内抖一个 sub-pixel 偏移(jittered 序列),跨帧累加。

第 1 帧:样本在 (0.25, 0.25)
第 2 帧:样本在 (0.75, 0.25)
第 3 帧:样本在 (0.25, 0.75)
第 4 帧:样本在 (0.75, 0.75)

四帧合起来等价于每像素 4× 超采样。这就是 Cook 1986 的思路在实时图形里的复用。

案例 4:景深为什么”自然”

胶片相机的景深来自光线经过透镜不同位置时走的路径不同。要在渲染里复刻:

  1. 把透镜看成一个圆盘
  2. 每个样本随机选透镜上一个点(jittered 在 2D 圆盘上)
  3. 从那个点出发追光线

聚焦平面上的物体,所有光线都会汇到同一像素,清晰;不在焦面的物体,每条光线打到不同像素,散开变模糊

这就是物理上发生的事,stochastic sampling 只是把它忠实地采样了一遍

踩过的坑

  1. “随机”不等于”乱”:纯均匀随机(白噪声)会出现——某些区域样本扎堆、另一些区域空白。Poisson disk 加最小距离约束才得到”看起来均匀”的噪声(蓝噪声)。

  2. 维度爆炸的暗坑:运动模糊把样本撒到 (x, y, t) 三维空间。如果三维都”独立”地 jitter,t 维上仍可能出现条带。Cook 后来提出 N-rooks / Latin hypercube——保证每条投影都覆盖均匀。

  3. 样本数从哪儿来:要让 noise 真的低于人眼阈值,每像素 ≥ 16 样本才稳。早年算力贵,每样本一条光线,电影一帧要算几小时。

  4. 不是越随机越好:纯 Poisson 比 jittered 慢一个数量级,工程上够用就好。绝大多数离线渲染器选了 jittered + 后处理 denoise。

  5. 白噪声 vs 蓝噪声常被混淆:白噪声是”频谱平坦”,蓝噪声是”低频少、高频多”。眼睛对低频更敏感,所以蓝噪声”看起来更均匀”。Poisson disk 自然产生的就是蓝噪声谱。

  6. 跨像素相关性破坏一致性:如果整张图共用同一个随机种子序列,会出现跨像素的”周期感”。每像素独立种子才稳。

适用 vs 不适用场景

适用

  • 离线渲染(电影 / VFX)的抗锯齿、运动模糊、景深、软阴影
  • Monte Carlo path tracing 的所有积分(半球方向、面光源、BSDF)
  • 实时引擎的 TAA / SSAO / 体积光采样

不适用

  • 极少样本场景(每像素 1 样本)→ 噪声过强,反而看起来脏
  • 需要可重复确定性的场合(比如某些科学可视化)→ 改用低差异序列(Halton / Sobol)
  • 1D 信号采样(如音频)→ 直接抗锯齿滤波即可,不需要 stochastic

历史小故事(可跳过)

  • 1982 年:Yellott 研究猴子视网膜,发现光感受器不是规则排列,是 Poisson disk 模式。猜想这就是为什么人眼”不发生 aliasing”。
  • 1984 年:Cook 发表 distributed ray tracing,第一次把”光线随机分布”用于渲染——但没系统讲为什么。
  • 1986 年:Cook 这篇论文把 1984 的工程做法讲透了它的理论根——是采样理论 + 视觉感知,不是物理模拟。同年 Kajiya 发表渲染方程,两篇论文加起来定义了之后 30 年的离线渲染。
  • 1990s:Pixar REYES / RenderMan 全面采用 jittered sampling。《玩具总动员》《虫虫危机》背后都是这套。

学到什么

  1. 错误的形态可以选——这是 Cook 1986 最深的一句话。aliasing 不是”对错”问题,是”哪种错眼睛能忍”
  2. 采样问题的本质是积分问题——要算的是像素覆盖的连续区域的平均,不是某个点
  3. 生物启发的工程优化:视网膜的随机排布给了 Poisson disk 灵感;生物已经解了这道题几亿年
  4. 理论 + 工程同步发表才有杀伤力:Cook 1984(工程)+ Cook 1986(理论)+ Kajiya 1986(理论)三篇定义了离线渲染
  5. 跨维度复用:同一招(抖一下采样位置)解决了抗锯齿、运动模糊、景深、软阴影、glossy 反射五件事——每一件单独研究都是一篇论文
  6. 工程取舍清单:质量从高到低是 Poisson disk > N-rooks > jittered > 白噪声 > 规则;速度反过来。Pixar 选 jittered 就是这条曲线的最佳工程点

延伸阅读

关联

  • cook-1984-distributed-ray-tracing —— Cook 自己 2 年前提出的工程原型,本论文是它的理论说明书
  • kajiya-1986-rendering-equation —— 渲染方程定义”要积什么”,stochastic sampling 给”怎么积”
  • perlin-1985-noise —— 同时期的另一种”用噪声”思想,但 Perlin 是构造噪声当纹理,Cook 是用噪声当采样误差
  • karis-2014-taa —— 30 年后实时图形里 stochastic sampling 思想的复用
  • cook-torrance-1982 —— Cook 自己更早的微表面 BRDF 论文,三篇加起来构成离线渲染的 Cook 三联

反向链接