关于抗锯齿

今天听 Gadio News 的时候,最末尾一段提到了希望有人能来讲讲抗锯齿技术。才疏学浅,但是前几年看 MC 的文章还是知道一点相关内容,所以就来看着维基写写看,如有不正之处劳请指出。

锯齿与抗锯齿

首先,什么是锯齿,以及为什么会出现锯齿。

我们的屏幕,是以一个个正方形的像素点组成的,而正方形的特性导致了在倾斜的线上,边缘必定会出现一个个突起的阶梯状“毛刺”,比如图上这种preview

这种阶梯状的“毛刺”就是典型的锯齿。而有了锯齿也就有了抗锯齿(Anti-Aliasing).

抗锯齿的一般过程就是将这个毛刺的边缘柔化,使图像边缘看起来更平滑。如图:img

各种算法简单介绍

抗锯齿算法种类非常多,下面的介绍顺序基本上是各种抗锯齿算法出现的时间顺序。

SSAA

超级采样抗锯齿(Super-Sampling Anti-Aliasing, 也可叫做 Supersampling 超采样)是最早也最简单粗暴的抗锯齿手法,它的原理非常简单,就是在渲染时将要输出的分辨率提升 x 倍,比如要输出 1920x1080 的分辨率到屏幕上,开启 SSAA 2x, 那么内部渲染时的分辨率就是 3840x2160, 然后 Downsampling 到 1920x1080 上,自然在许多纹理边缘上就显得平滑许多。但是这种方式太太太吃资源了,所以又开发出了新的算法。

在 Nvidia 发布二代 Maxwell 架构的时候,同时发布的 DSR 技术中就有 SSAA 的影子,技术思路同样是以更高分辨率渲染的原始画面输出到显示器分辨率上来得到更加精细平滑的画面。

MSAA

SSAA 太吃资源了,我们的硬件暂时还跟不上,怎么办?于是就有了多重采样抗锯齿(Multi-Sampling Anti-Aliasing), 它跟 SSAA 的区别就是,MSAA 只对于多边形的边缘进行抗锯齿处理。比如一个红色的圆,只对圆周作抗锯齿多重采样计算,但是圆周以内的部分则不会处理。这种方式下的画面锯齿得到了一定的抑制,而抗锯齿需要的资源也大幅下降到可接受的范围中。所以 MSAA 也逐渐成为目前被使用的最多的抗锯齿技术。

但是 MSAA 也有其局限之处,比如对于半透明物件、边缘不明确或者非常复杂的物件比如密集草丛、铁丝网这类的抗锯齿处理就比较力不从心。

CSAA & CFAA

历史进入 Direct 10 时代,NV 方先声夺人发布了 G80 系列,同时带来了覆盖采样抗锯齿(Coverage-Sampling Anti-Aliasing)技术,主要改进了取样类型从而使得抗锯齿效率提升,资源占用量也得到减少。举例来说,如果使用 16x MSAA,需要在周围取得 16 个采样点的色彩值和 Z 轴值,然后保存这些数值进行计算。而 16x CSAA,则全部在被采样的像素点中心取得色彩之和Z轴值,然后对比并去掉同样的数据。一般来说,16x CSAA 后只需要保存 4 份色彩值和 Z 轴值即可。换句话来说,4x MSAA 耗费的资源和 16x CSAA 是相同的,但是,16x CSAA的画面效果相比 4x MSAA 更好。

同期 ATI 在发布 R600 系列时也带来了可编程过滤抗锯齿(Custom Filter Anti-Aliasing)技术。简单的来说 CFAA 就是扩大取样面积的 MSAA,比方说之前的 MSAA 是严格选取物体边缘像素进行缩放的,而 CFAA 则可以通过驱动判断对影响锯齿效果较大的像素进行缩放,以较少的性能牺牲换取平滑效果。

但是由于种种原因,CSAA 被接受程度更高一些,不少游戏就直接加入了 CSAA 选项。而 CFAA 由于需要在显卡驱动面板中进行调试而渐渐被用户所遗忘。

MLAA & FXAA

在 CFAA 被遗忘之后,AMD-ATI 带来了形态抗锯齿(Morphological Anti-Aliasing).

不同于上面几种需要对多边形边缘进行分析计算的算法,MLAA 是一种后处理技术,发生在整个 3D 计算完成即将输出画面到屏幕上前,打个比方就是你拍完照用 Photoshop 处理的过程。

MLAA 的实际效果还是非常不错的,但是资源耗用还是有点厉害的。它的最大优势就是不需要游戏来支持它,因为是后处理技术所以在显卡驱动面板中打开就能用而且兼容性非常好。但是由于其仅仅使用颜色数据来判断抗锯齿边缘,因此 MLAA 的应用可能导致无法辨识到底哪些边缘需要进行抗锯齿计算。特别是一些不需要抗锯齿的地方,如文字,表格等,可能都由于不当抗锯齿而显得圆滑甚至怪异。

这边 A 家出了新抗锯齿技术,老冤家 NV 当然也不甘落后,在 Fermi 上推出了快速近似抗锯齿(Fast Approximate Anti-Aliasing)。

FXAA 和 MLAA 一样,也是一种后处理抗锯齿,两种 AA 在原理上相似,但是由于 FXAA 可以在 AN 两家的卡上都可以用而 MLAA 则由于部分计算处理依赖于硬件所以只能在 A 卡上用,最后导致 FXAA 被广泛的采用了。而且同时期 FXAA 的性能损失比 MLAA 更小,而效果上基本能接近 4x MSAA 的画面,虽然同样还是会出现“字体破坏”的情况。

TXAA

在抗锯齿这条路上,众多程序员以及各种“家”的探索是不会停下来的。在 Kepler 架构发布的同时,NV 也带来了新的 TXAA(Temporal Anti-Aliasing 可称为“时间性抗锯齿”)技术,据 NV 自家的介绍,这项技术集时间性过滤器、硬件抗锯齿以及定制的 CG 电影式抗锯齿解算法于一身。

原有的抗锯齿技术在解决静态画面的锯齿上可以说已经达到了瓶颈了,但是在动态画面上,有锯齿的部位很容易出现闪烁。如同其名字中的“时间性”,TXAA 旨在解决“时间性抗锯齿”,也就是动态画面中的锯齿闪烁等问题。而其同时提供着不输于 8x MSAA 的静态画面抗锯齿效果。

TXAA 可以说是目前被采用的较多的抗锯齿算法中最厉害的一种了,但是它一是需要硬件电路配合,二是吃资源,以性能换画面,所以也基本上是中高端 N 卡用户用的。

结语

目前主流的一些抗锯齿技术大概就是这么多了,本文很多内容都是参考中文互联网上的一些文章写成的。第一次在机核发文,存在的许多不足之处也请多多包涵。