Anti-alias的前世今生(一)

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

Anti-alias,简称AA,在图形学中广泛地用于提升渲染质量。经过几十年的发展,AA也从离线渲染逐步普及到了实时渲染的领域。本系列文章将总结一下在实时渲染中使用的AA方法的前世和今生。本片集中讨论硬件提供的AA方法。

AA

图1. 一个像素内部的采样点。16个红圈表示16个采样点,蓝色和黄色是覆盖了这个像素的两个三角形。

SSAA

Super Sampling Anti-Aliasing是最直观的一种AA方法。实现方法之一就是渲染一个大图,然后downsample,这相当于在每个最终像素内部做了一个均匀 分布采样。更通用的描述是,每个像素分布多个采样点(可以均匀分布、Poisson分布、随机分布、抖动分布等),每个采样点都有独立的color和 depth,pixel shader在每个采样点都执行一遍。如图1的情况,会得到1个白色,1个浅蓝色和14个黄色的采样点。最后这个像素的值是这16个采样点的平均,也就是 ((1, 1, 1) +  (0.77, 0.77, 1) + 14 * (1, 1, 0)) / 16 = (0.98, 0.98, 0.125)。在这些方法中,SSAA质量最好,毕竟是个最暴力的方法。在D3D 10.1+上可以选择per-sample或者per-pixel执行pixel shader,也就是直接支持了SSAA。

性能统计(采样数为N,下同):每个像素里PS执行次数为N,占用空间N个color + N个depth。

MSAA

SSAA需要在每个采样点都执行一次PS并保存color和depth,时间和空间开销都是惊人的。Multi-Sampling Anti-Aliasing的出现极大地改善了这点。MSAA在每个像素只执行一次PS,输出颜色写入所有通过depth-stencil测试的采样本 中。在Shader Model 3之前,PS的输入一定取自像素的中心;后来加入了centric插值,PS的输入属性就可以是三角形所覆盖的所有采样点的中心:

Centroid Sampling

来自http://www.confettispecialfx.com/multisample-anti-aliasing

如图1的情况,没有centric插值的话,蓝色三角形的两个采样点将都得到纯蓝的颜色(外差而得),最终像素的颜色就是(2 * (0, 0, 1) + 14 * (1, 1, 0)) / 16 = (0.875, 0.875, 0.125)。有centric插值的话就是个更正确的浅蓝色((1, 1, 1) + (0.77, 0.77, 1)) / 2 = (0.885, 0.885, 1),最终像素颜色是(2 * (0.885, 0.885, 1) + 14 * (1, 1, 0)) / 16= (0.98, 0.98, 0.125)。如下图所示:

性能统计:每个像素里PS执行次数为每个覆盖到该像素的三角形一次,占用空间N个color + N个depth。

CSAA

MSAA虽然解决了计算的问题,但存储量还是很大,尤其是采样率到了8以上。NVIDIA在G80及以上的GPU增加了Coverage Sampling Anti-Aliasing的方法。CSAA解耦了color/depth的buffer和coverage的buffer,可以用较少的color /depth空间来存储原先高采样数才能得到的质量。比如图1的情况,用CSAA 16x来渲染,就会把一个像素分成左上、右上、左下和右下4块区域,每块区域有4个coverage采样点,但共享同一个color和depth。对于图 1的情况,结果就是,(0.25 * (0.885, 0.885, 1)  + 0.25 * (0.885, 0.885, 1) + 3.75 * (1, 1, 0)) / 4 = (0.98, 0.98, 0.125)。

性能统计:每个像素里PS执行次数为每个覆盖到该像素的三角形一次,占用空间M个color + M个depth,M小于N。

总结

这三种方法是常见的硬件直接支持的AA方法,下篇文章将讲述各种基于post process的AA方法。

posted on 2011-05-16 12:05  龚敏敏  阅读(4600)  评论(3编辑  收藏  举报