转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=1129

上一篇文章Anti-alias的前世今生(一)介绍了硬件支持的AA方法,本篇将重点阐述新兴的基于post process的AA。

SSAA、MSAA、CSAA这些方法虽然硬件直接支持,但带来的额外开销不可小视。一方面是它们对存储空间带来的冲击是惊人的。尤其在非桌面平台上,内存本来就不多,如果还需要AA的话就吃不消了。如果同时使用了MRT和AA,显存开销更是天文数字。另一方面,这些方法对“edge”的考量都是primitive的边界,不管这个edge是否真的需要AA,所以会浪费很多计算量。

GPU Gems 2的第九章Deferred Shading in S.T.A.L.K.E.R.在游戏界第一次宣传了Deferred Shading的概念,同时也提到了Deferred框架无法使用硬件MSAA的问题。虽然Deferred Lighting部分解决了该问题,但再次渲染一边场景的代价还是不小的。更重要的是,由于Deferred框架的引入,人们终于开始正视MSAA的实际上造成了很多时间和空间的浪费。于是乎这几年基于post process的AA蓬勃发展,大有取而代之的气势。

Edge AA

Edge AA就是Deferred Shading in S.T.A.L.K.E.R提出的方法,根据邻居的depth和normal的差异程度做一个边缘检测,每个像素可以得到一个权重,表示“像边缘的程度”:

Weight Computed by the Edge-Detection Shader

根据这个权重,就可以把邻居像素的颜色拿来插值,得到AA的效果。

在GPU Gems 3第19章Deferred Shading in Tabula Rasa中,NCsoft对Edge AA做出了一些小改进,边缘检测不再依赖于图像分辨率,更加稳定。

Directionally Edge AA

Edge AA开创了post process AA的时代,但它的质量还是不足以与硬件AA抗衡的程度。AMD在HPG09上的论文A Directionally Adaptive Edge Anti-Aliasing Filter改进了Edge AA,不再采用独立的edge点来决定AA混合的方式,而是根据edge点周围的状况确定出isoline,然后根据isoline的垂直方向来确定混合的方向。这样一个边界就会沿着朝向来混合,还原出更加精确的sub-pixel信息。这种方法进入了AMD的驱动,只要打开Adaptive AA就会自动启用。

MLAA

Adaptive Edge AA提出了以线代替点的研究方向,但isoline的计算量毕竟比较大,启用了之后对渲染性能下降明显。Morphological Antialiasing再次在这个方向作出了努力。它不计算isoline,而是把edge分门别类,总结成Z、U、L等几种特定的形状,而Z和U都可以分解成L。

Shapes

最终根据L划出一个三角形,确定混合区域。这样就省去了所有繁重的计算,提高AA速度。在AMD较新的驱动里,MLAA取代了Directionally Edge AA成为Adaptive AA的首选。MLAA的框架又派生出多个不同的方法:

CPU MLAA

Intel在HPG09上的Morphological Antialiasing一文是在CPU上实现的。代码用了非常深的分支来判断edge形状,完全是针对CPU优化的,不适合GPU硬件,也不适合实时渲染的情况。

GPU MLAA

SIGGRAPH 2010 poster的Practical morphological antialiasing on the GPU,通过建立SAT来判断edge形状,需要log(width)+log(height)个pass。在确定了L之后,需要查询一个预计算的512×512 R32F的纹理,里面每个texel对应了一个特定大小的L所需要混合的面积。也就是边长最大是512个像素。可以看出这种方法非常暴力,虽然可能比读回CPU快,但开销还是很大。

Jimenez’s MLAA

GPU Pro 2里的文章Practical Morphological Anti-Aliasing提出了一个更实用的GPU MLAA方法,命名为Jimenez’s MLAA以示区分。在这种MLAA里,Z和U不需要分解成更简单的L,直接用一个预计算的表来做查询。每个像素根据自己在形状里的位置在查找表里寻找需要混合的各个像素。720p的分辨率下,这种方法在一般的情况下能达到Xbox 360上3.79ms,Geforce 9800 GTX+上0.44ms。同等条件下8x MSAA需要5ms。

FXAA

NVIDIA在Graphics SDK 11里面提供了一个称为Fast Approximate Anti-Aliasing的方法。该方法很接近于MLAA,但只识别长边,而不识别形状。有了长边之后,就可以根据边和像素的求交来估算每个像素中sub-pixel的覆盖率,并进行AA混合。后来Timothy Lottes还发展出了FXAA II,质量有所下降,速度提高了,在Xbox 360上,720p的分辨率可以做到2.0ms。

DLAA

另一个在GDC11上公开的AA方法称为Directionally Localized Anti-Aliasing(前面介绍的Jimenez’s MLAA和FXAA也在GDC11的时候公开的,这也扎堆)。这种方法比较另类,它在垂直方向模糊后的图像上做水平方向边缘检测,得到的结果blend回去就得到AA后的图像。

DLAA

左图为AA之前的,右图是经过DLAA的

DLAA还是比较快的,在Xbox 360上,720p需要2.2ms。

本篇介绍了几种基于post process的AA方法,下一篇讲讨论如何把硬件AA和post process AA结合起来。

Adaptive Edge AA