光栅化过程中的采样与反走样(MSAA),频域与滤波
本文由 简悦 SimpRead 转码, 原文地址 zhuanlan.zhihu.com
采样(sampling)
何为采样?是指从总体中抽取个体或样品的过程。用程序的思维来解释的话,就是给定一个连续的函数,然后我们通过不同的输入来获取函数的值。例如有个函数 y = f(x) ,我们分别求 x = 1,x = 2,x = 3… 时 y 的值。采样即把一个函数给离散化(Discretize)的过程,在图形学中有广泛的应用,例如在光栅化过程中取每个像素的中心点,就是在采样。
采样频率
采样频率可以理解为抽取样本的间隔,例如上面我们采样的是 x = 1,x = 2,x = 3…,间隔为 1。如果改成 x = 1,x = 3,x = 5… ,间隔为 2,那么就代表频率变慢。而改成 x = 0.5,x = 1,x = 1.5… ,间隔为 0.5,那么就代表频率变快。
应用到光栅化里的话,我们可以把每个三角形当做是无数个点组成的,而我们的屏幕又由一个个的像素组成,这些像素的中心点对应到三角形中的某些点,等同于所有点中所抽取出的样本。那么采样的间隔自然是我们像素的实际物理大小。因此若屏幕大小不变,分辨率越高(即像素越多,像素的中心点物理间隔越小),采样的频率越高。
上面介绍的属于采样二维空间中的位置信息,此外我们还可以采样时间,例如下图,便是采样了不同时间人挥球的动作,进行了显示。
走样(Aliasing)
走样,什么是走样?汉语字典给的定义是:变样,失去原有的样子。这个就很好理解了,我们光栅化一个三角形,得到的结果因为锯齿导致它变样了(如下图),那么锯齿就是我们走样的一种体现。
锯齿与采样的关系
从图中我们可以看出,导致锯齿的原因是由于每个像素内只存在一种颜色,同时每个像素又有一定的大小,这些锯齿就是在三角形边缘的一个个像素。因此若我们的像素越大那么锯齿也就越大越明显,像素越小锯齿也就越小越不明显。
回到采样上,因为我们在光栅化操作时,采样的是像素的中心点。那么像素越小,说明像素的中心点越密集,也就是说我们的采样频率越高。也就是说锯齿出现的原因是因为我们的采样频率不够高。
但是上面所说的提高分辨率来提高采样频率其实是属于物理 / 硬件层面上的优化了(直接换屏幕了),若我们要在分辨率不变的情况下做抗锯齿操作呢?也就是我们后面要介绍的反走样操作。
像锯齿这样,由于采样所造成的一些问题,在图形学中我们称之为 Sampling Artifact,这些问题造成的现象也就是走样。
Sampling Artifacts(瑕疵)in Computer Graphics
锯齿(Jaggies)
我们前面提到的锯齿就是采样产生的一种问题。
摩尔纹(Moire)
摩尔纹是一种会使图片出现彩色的高频率不规则的条纹,也是采样所造成的问题之一。我们生活中使用手机拍摄显示器屏幕的时候,拍出的照片往往就好出现扭曲的纹理,其实就是摩尔纹。
我们要在图像上进行复现也很简单,我们把屏幕上的一张大小为 m* n 的图去掉所有奇数行和奇数列的像素,然后把剩下的像素重新拼接在一起(等于缩小了图片),然后依旧按照原始的 m*n 大小显示,就会出现摩尔纹。例如下图:
用采样理解起来也很简单,例如我们一个 2*2 的 4 个像素,原本采样 4 个点,四个点颜色不尽相同,去掉奇数行奇数列后只剩右上角的 1 个像素,然后又要显示成 2*2,那么就是四个像素都变成了一个颜色,也就是右上角那个像素的颜色,等同于只采样了右上角 1 个点。
也就是说原本我们每个像素采样一次,变成了每四个像素采样一次,使采样频率降低,这种情况我们称之为欠采样(Undersampling)。
车轮效应(Wagon wheel effect)
在生活中,有些高速行驶的汽车,但是我们的眼睛看它的车轮却反而像是在倒着转,这也是采样所造成的问题,我们称之为车轮效应。
造成这个问题的原因是人眼在时间上的采样,跟不上运动的速度,时间上采样慢也就是采样频率低。
造成走样的原因
从上述种种 Sampling Artifacts 造成的走样来看,都是由于采样频率低(采样慢)跟不上物体的实际变化速度。更专业的说法是,信号(Signals)变化的太快(高频,high frequency),而我们的采样太慢。
这里的信号变化怎么理解呢?车轮效应我们很好理解,信号变化快就是车轮转的太快了,随着时间的变换,车轮的旋转角度发生了变换。但是对于光栅化过程,怎么理解这个信号变化呢?
我们前面讲过光栅化是把真实的场景映射到屏幕上的过程。我们可以把真实的场景内容看作是一个由 m*n 个像素组成的(忽略 z 轴),m 和 n 趋向于无限大,为了方便理解和描述,我们称它们为原始像素。那么我们的光栅化等于把这 m*n 个像素进行缩减,使其显示在 x*y 个像素的屏幕上,x 和 y 远远小于 m 和 n,我们称之为屏幕像素。简单来说,我们等同于把一幅高精度的图像(现实)变成了一幅低精度的图像(图片),这里的信号,我们可以称之为图像信号,信号变化就是原始像素中每个像素间的颜色变化,颜色本质就是一串信息,例如 RGB 值。同时也说明图像的信号变化并不是随着时间而变换,而是随着空间中 x 和 y 的值的变化而变化,这种我们称之为空间域(Spatial Domin)。那么信号变化快就是指原始像素间颜色发生了骤变,例如白色变成黑色等,反之两个像素之间颜色没有发生什么变化就是信号变化慢。
这也就很容易理解走样的说法了,如果信号变化慢,即周边一群像素的颜色相似,那么我们采样慢,即只取其中一点,就不会造成什么问题。但是若信号变化快,周边一群像素都是五花八门的,我们采样慢就会造成走样。这也是锯齿为什么都发生在三角形边缘的原因,因为在三角形内部信号变化慢,但是在三角形边缘信号变化往往会骤增。
反走样(Antialiasing)
既然我们的采样结果走样了,那么我们就要做一些优化来尽量的避免走样,也就是反走样操作。
例如我们平时玩游戏,在画质设置里往往就会有抗锯齿的操作(即反走样),如下图是最近在玩的 GTA 和塔科夫的抗锯齿设置。

而对于这样的采样方式,我们可以理解为,有一个函数,它只在一些特定的地方有值(需要采样),而在其他地方的值都为 0(不需要采样),这样的函数我们称之为冲激函数。
例如最简单的冲激函数即为:
代表着 t=0 时有值(无穷大)而 t 为其他值时,结果都为 0。
采样与函数
前面说了信号是一个函数,采样是一个冲激函数,那么采样后的结果在这里我们就可以理解成这两个函数相乘所得到的结果。

普通采样和超采样的对比效果如下:

通过超采样,我们就可以计算出每个像素的平均颜色,如下图:
![](data:image/svg+xml;utf8,