Anti-alias的前世今生(二):Post process based AA

转载请注明出处为KlayGE游戏引擎,本文地址为http://www.klayge.org/2011/05/17/anti-alias%e7%9a%84%e5%89%8d%e4%b8%96%e4%bb%8a%e7%94%9f%ef%bc%88%e4%ba%8c%ef%bc%89%ef%bc%9apost-process-based-aa/

上一篇文章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结合起来。

posted on 2011-05-17 13:18  龚敏敏  阅读(2403)  评论(0编辑  收藏  举报