抗锯齿技术深度解析

前一段上网扒文的时候我发现了Beyond3D的这篇文章1,觉得挺有意思。相较于目前大部分中文媒体2和论坛对抗锯齿的探讨而言,这篇文章解说的更浅更系统,涵盖的范围更广,案例也比较生动。因此从一周前我和FanWu同学开始陆陆续续对这篇文章进行翻译润色,并进一步增加了各种注释以及一些我们认为有助于理解文中概念的知识和文章,希望对想要深入了解抗锯齿的同学或游戏爱好者有点启发。(除了大量脚注外,其他添补的内容将以粗体展示)

语言水平有限,若发现文中有语病或者其他错误恳请指正。目前仍为Beta版,持续修订中。

需注意的是Aliasing在3D渲染中不是指锯齿,而是指更广的的渲染失真的概念。锯齿只是渲染失真的一个主要表现,但在说到FSAA(Full Screen Anti-Aliasing)等技术的时候,一般国内媒体会翻译为“抗锯齿”——这实际上是一个不太准确的表述。但为了照顾大部分读者的习惯,下文仍将Aliasing翻译为锯齿,仅在非讨论锯齿部分翻译为其他名词以示区别。

——————————

锯齿大概是3D渲染瑕疵中最火的话题之一,但游戏玩家中并没有多少人对这个问题有着较为全面的了解。这篇文章将对实时抗锯齿(特别是游戏中的应用)进行一次较为全面且深入的解说。

在开始解说前先讲讲性能问题:虽然实时渲染的性能是重中之重,但这篇文章主要还是聚焦在为什么要抗锯齿以及如何抗锯齿两个方面。当然文中也会粗略提及各种抗锯齿手段对性能的影响,但基于benchmark等更深入细致的性能分析将不会出现在这篇文章中。

知己知彼,百战不殆。

——孙武

正如孙武所说,想要战胜一个敌人就需要先了解它,而我们要做的第一件事情就是了解渲染瑕疵的成因。

Aliasing (失真) 这个术语最早出现在信号处理这门学科中,指的是当一个连续信号被采样后和其他非一致信号混淆的现象3。在3D渲染中,这个术语有着更特殊的意思——它涵盖了所有3D渲染光栅化4后产生的画面瑕疵

3D场景渲染在光栅化之前是连续信号,但在进行像素渲染(对每个像素生成相应的色彩值)的时候就不得不对连续信号进行采样以获得能够输出到显示器的结果。反锯齿的目标就在于让最终输出的画面和最初所要渲染的场景尽可能接近,修复那些恼人的渲染瑕疵。

8×8像素阵列原始三角形栅格化后的三角形理想采样的三角形

上图展示了光栅化流程对黑色背景上白色三角形采样后产生的失真。在传统渲染管线的光栅化过程中,每个像素的中心被采样一次:如果这个中心位于三角形内,那么这个像素是白色的,否则是黑色的。这种采样策略不可避免的产生了阶梯状锯齿——一种最为常见的渲染瑕疵。

理想中的光栅化流程需要衡量每个像素被三角形覆盖的精确的量。如果一个像素被覆盖了50%,则它的颜色组成应该是50%白和50%的黑(灰色)。如果覆盖量低于50%,那么它的颜色就相应的偏黑,反之亦然。基于这种抗锯齿策略最后产生的光栅化结果可以在“理想采样的三角形”这张图中看到。但是由于庞大的计算量,这种策略在实时渲染中几乎不可行。

失真的类别

所有的渲染失真都可以归因于采样问题(用有限的像素展示无限的细节),且每种失真具体的成因将和哪种反锯齿最有效息息相关。例如在后文中,你将看到有些反锯齿方法对于简单的几何失真有效,但对其他类型的锯齿则无能为力。因此,为了能探讨不同反锯齿手段的优势和劣势,我们先将3D渲染的瑕疵根据其成因简单归纳为5个类别。

不同种类的渲染失真,从左到右分别是

  • 包含透明纹理的矩形
  • 白黑相间的扇形图案
  • 粗细不同的黑线(1像素到0.4像素),0.5像素粗的白色正弦波图案
  • 包含不同颜色面的六面体
  • 复杂草地图案的倾斜平面
  • 像素渲染器生成的纹理

几何失真

这应该算是最常见的失真类型。当一些场景的几何体的边缘(一般为三角形)和一个像素部分覆盖的时候,由于对非完全覆盖的采样过于粗糙(1像素1采样点),栅格化后就出现了锯齿。

透明失真

当一张贴图包含部分透明(镂空)图案的时候(例如上图左上角的铁丝网),由于贴图本身就是由个数有限的像素阵列所组成,当判断被渲染几何体透明与否的时候会将贴图的栅格化特性带入最后的渲染结果。这样一来,就算是几何体内部也可能会有锯齿。

子像素失真

当栅格化后的物体小于一像素时,就产生了子像素失真。子像素失真最常见于非常细小的物体,例如场景中的塔尖、电话线或电线,甚至是距离屏幕足够远的一把剑。虽然这类失真也可以算是几何失真的一种,但在反锯齿算法的设计中需要被特殊对待,因而另归一类。这个问题在近期的游戏渲染中被越发重视,在后文中也会详细介绍。

8×8像素阵列原始线段栅格化后的线段理想采样的线段

纹理失真

当包含大量高频信号的纹理未被充分采样的时候(特别是在各向异性采样的场景中,最典型的就是延伸到屏幕深处的一个平面,例如地面),则会出现纹理失真。通常这种失真并无法从静态的截图中体现出来,但在下面的动态图中可以看到,当纹理移动的时候出现了像素闪烁的现象,这就是纹理失真的表现之一。

纹理失真通常可以使用mip-mapping或者高质量的纹理过滤算法来避免。但有时候这些方法仍然会有问题。例如当一些GPU驱动对一个高度各向异性的纹理进行降采样的时候,依然会出现纹理失真的现象。

渲染失真

像素渲染器在对每个像素进行颜色填充时产生的失真称为渲染失真。这种现象通常在硬光照渲染中出现,例如基于法线贴图的镜面高光,卡通渲染,以及边缘光照等等。
所有的3D纹理都是基于贴图吗?显然不是的,除了通过贴图给3D骨架上色外也能通过像素着色器辅以相应的数学方法来填充物体的颜色。例如我有一个立方体,我希望它每一面都是一半蓝一半白,那么我就可以写一个Shader Program来进行坐标的判断并填入相应的色彩(例如大于0.5填蓝,小于等于0.5填白,而卡通渲染(Toon Shader)也只不过是在这个基础上多加几个分界点罢了)。不出意外的是,由于像素着色是在像素阵列上执行,立方体的颜色界线会有锯齿

基于采样的反锯齿技术

在了解了所有失真的类别后,终于可以开始分析现今的抗锯齿技术了。这些抗锯齿技术可以分为两类:一类是通过提高渲染时的采样数来减少锯齿,另一类则是通过对已渲染好的图片进行分析和后期处理来减少锯齿。基于采样实现的反锯齿技术更为直观,因此这里从采样反锯齿开始介绍。

让我们回顾一下前文那个8×8像素阵列中绘制三角形的例子。传统的渲染仅采样像素中心,从而导致非垂直或水平的边缘出现了阶梯状锯齿。而如果精确计算每个像素的覆盖量,由于运算量巨大,也不现实。

因此不难想到我们可以增加每个像素采样的数量,如下图所示:

每个像素的中心用红色点表示,而我们的采样点则用浅蓝色点表示(每个像素四个采样点)。在上文三角形栅格化的案例中,如果一个三角形没有覆盖一个像素内的任何采样点,那么这个像素是黑色的;反之如果覆盖了所有采样点,像素则是白色的。如果四个采样点中的一个被覆盖了,那么这个像素的颜色将会由25%的白色和75%的黑色构成,以此类推。

这个简单的概念就是所有基于采样的抗锯齿技术的基石。倘若一个像素的采样点趋近于无穷多,那么最终的效果就会无线趋近于之前所展示的“完美”的光栅化效果。因此,抗锯齿的质量和采样点密切相关——当然也与性能密切相关。通常在游戏中每个像素会使用2个或4个采样点,而8个以及以上的采样点通常被应用在高端电脑的渲染中。

除了采样数量,采样位置、采样类型和采样混合模式5也会影响最终的画面质量。

 

采样位置

采样点的放置对最终画面质量有着至关重要的影响。特别是在游戏渲染中,由于采样点数量少,采样点的放置就更为重要。在之前的例子中,采样点的放置使得像素排列等效于4倍放大(即1个像素等效为4个)。这种简单的方法可以通过直接渲染一个更大的画面来实现。由于采样点排列的特性,这种抗锯齿被称作OGAA(ordered grid anti-aliasing)。若是通过渲染比屏幕分辨率更高的画面后缩小到屏幕空间时,这种方法有时也被称为降采样。

然而这种规整的采样点排列往往不是最优解,特别是当对付游戏中经常出现的近似垂直或者近似水平的几何边缘的时候效果往往不好。下图展示了为什么这样的采样点排列并不理想,同时为什么更加稀疏的排列效果更好。

原始边缘理想采样的边缘OGAA采样的边缘SGAA采样的边缘

对于近似垂直的情况,理想的四点采样将会对这个几何体边缘产生五种不同的灰度值——0%白,25%白,50%白,75%白以及100%白。然而在上图情况中,规整的四点采样仅能生成3种灰度——黑,白以及灰(50%黑+50%白)。产生这样结果的原因在于垂直两个相邻采样点位于同一列,当其中一个点被近乎垂直的集合体边缘覆盖的时候,另一个点也很有可能同样被覆盖。

为了缓解这个问题,我们可以将采样点稀疏摆放在不同的列。对于抗锯齿来说,理想的摆放应当是稀疏的,也就是说对于N个采样点,任意两个采样点不会在一个NxN网格的同一列、行以及对角线上。通过对著名的N皇后问题6求解可得到满足这种条件的采样点摆放方式,在此不再赘述。这种稀疏摆放采样点的抗锯齿被称作SGAA(sparse grid anti-aliasing,稀疏栅格抗锯齿)。

采样类型

最直接的采样抗锯齿对每个采样点都进行了真实的运算。虽然这样的采样方式可以消除各类渲染失真,但也非常耗费资源。简单来说,N倍采样将会给像素渲染、光栅单元、内存带宽以及内存容量施加N倍的计算压力(想象当渲染分辨率扩大sqrt(N)倍的情况)。这种对每个采样点都进行独立计算的采样也被称为SSAA(super-sampling anti-aliasing,超采样抗锯齿)

在进入21世纪后,MSAA(multi-sample anti-aliasing,多重采样)开始作为SSAA的一种优化解被广泛应用。和SSAA不同的是,MSAA对每个像素点仅进行一次计算。但对深度和模板值仍计算N次。这样一种策略使得几何体边缘抗锯齿的效果接近SSAA并大幅降低性能开销。但由于MSAA仅针对几何体边缘进行抗锯齿,其他类别的失真(透明失真、纹理失真和渲染失真等)都无法被消除。当硬件支持Z信息和颜色缓冲压缩时,MSAA带来的内存带宽开销会进一步缩小,而现今大部分GPU都已经支持这些特性。

第三种采样类型则是NVIDIA在2006年引入的CSAA(coverage sampling anti-aliasing 覆盖采样抗锯齿)。 CSAA在保留了MSAA对像素点计算, 深度和模板值处理方式的同时, 还增加了覆盖采样(Coverage Sample)。 后者并不储存任何着色、 深度或模板信息, 而是储存了一个二进制的Coverage值。在采样混合(Sample Aggregation)的过程中, 这个新引入的Coverage值被用作参考。 实际上,CSAA可以被看成是对MSAA的扩展, 在原有的MSAA基础上加入了覆盖采样。 CSAA增加了少量性能开销(通常对于4xMSAA来说 7),但是在输出质量上却能企及8x甚至16x MSAA的水平。 较新的NVIDIA显卡提供了四种CSAA模式8:8xCSAA(4xMSAA/8覆盖采样),16xCSAA(4xMSAA/16覆盖采样),16xQCSAA(8xMSAA/16覆盖采样),和32xCSAA(8xMSAA/32覆盖采样)。AMD也提供了类似的抗锯齿技术,分别为:4xEQAA(2xMSAA/4覆盖采样),8xEQAA(4xMSAA/8覆盖采样),16xEQAA(8xMSAA/16覆盖采样)。

CSAA进一步将覆盖率这个特性从采样点中剥离出来。通过针对性地增加覆盖采样信息,CSAA获得了更高的抗锯齿效率,如下面组图所示:

无AA4x MSAA16x CSAA

采样混合模式

影响采样抗锯齿质量的最后一个要素就是采样混合模式,即将采样点混合为一个像素的策略。下面的组图展示了几种常见的混合滤镜。在这个3×3的像素阵列中,浅蓝色的点代表采样的位置,而黄色部分则表示混合滤镜所覆盖的范围。

Box混合梅花形混合Tent混合

最常见的混合方法是以相同权重混合每个采样点,这被称作box filter,也是所有传统MSAA所采用的模式。

早期的一种改进的混合方法被称作梅花抗锯齿(Quincunx Anti-aliasing)。这种方法适用于采样点个数很少的情况。在梅花抗锯齿的混合模式中,每个像素点只计算两个采样点,其中一个在像素的中心点,另一个则在像素的边角(矩形的顶点)上9。但是在混合的过程中梅花形抗锯齿却混合了5个采样点的信息(中心1个和四周4个),这使得采样点个数不多的情况下的抗锯齿效果明显增强,却也带来了画面锐度降低的问题。这是由于一个像素点过多地混合了周边的采样点信息而使图像边缘变得模糊。

一种更灵活的方法则出现于2007年AMD的HD2900系列图形卡中。HD2900系列提供了可编程的混合能力,并借由这种能力实现了narrow tent和wide tent两种混合模式。如上图所示,这两种新型采样模式在混合采样点时并没有使用相同权重,而是根据采样点离像素中心的距离决定相应的混合权重。narrow和wide两种混合模式的区别仅在于其使用的过滤核心(filter kernel)的大小上10。这种混合模式可以和不同采样数量搭配使用,其效果可以在下一个部分找到。相较于梅花形抗锯齿,这种抗锯齿模式可以说是画面锐度和抗锯齿力度的一种新的权衡。

各种采样抗锯齿的对比

以下的组图展示了上面所讨论的几种不同倍率抗锯齿的画质对比。需要注意的是,“理想状态”代表的是和未采样时最接近的栅格化结果,它是由8xSGSSAA和4×4 OGSSAA叠加采样后得到的。

理想状态无AA2x MSAA2x SGSSAA

4x MSAA4x SGSSAA8x MSAA 8x SGSSAA

8x MSAA + Alpha-to-coverage2×1 OGSSAA1×2 OGSSAA 2×2 OGSSAA

4x Narrow Tent6x Narrow Tent6x Wide Tent 8x Wide Tent

在观察对比图片的时候有几点值得注意:SGMSAA和SGSSAA在几何边缘抗锯齿上有着近乎一样的效果,但SGMSAA对于透明失真、渲染失真等就没有抗锯齿效果。当对比4x SGSSAA和2×2 OGSSAA的时候,可以很容易看到OGSSAA对近似垂直和水平的线条处理有明显的劣势。此外如果只有两个采样点,OGSSAA只能进行垂直或者水平的抗锯齿(2×1或1×2),而更稀疏的采样点摆放则可以兼顾二者的抗锯齿。

在采样点混合方面,可以观察到非传统box filter的混合模式往往带来更好的抗锯齿效果,但不可避免的会带来画面锐度的降低。

最后值得注意的一点是,所有这些基于采样的抗锯齿模式在子像素失真的处理上都一样优秀,而对于后文马上要提及的后处理抗锯齿而言情况则并非如此。

 

后处理抗锯齿(分析抗锯齿)

虽然基于采样的抗锯齿算法不仅原理简单,在采样点足够的情况下也有很优秀的效果,但在性能方面仍然会带来巨大的开销。此外基于采样的抗锯齿在近期流行的渲染模式中(例如延迟渲染)基于各种原因更难被实现。由此诞生了另一种非基于采样的抗锯齿方法——后处理抗锯齿。这个方法渲染出未使用抗锯齿的原始画面(无任何采样和缩放),随后尝试通过对成品画面的分析来减少锯齿和失真。

 

为什么延迟渲染和MSAA相性不合?这和MSAA当初设计的原理相关。传统的渲染管线的流程是顶点–几何–像素的渲染流程。在渲染初期对GPU输入顶点信息,经由几何处理进行相应的插值等运算,最后进行像素渲染(可能要进行数次像素渲染,特别是在多光源+阴影的情况下,也被称为multi-pass)

虽然这种渲染流程很直白(类似与现实中作画的流程),但由于渲染过程中难以判断被遮蔽的物体,将会进行很多无用的计算。这个问题在近期游戏发展的过程中,特别是引入多动态光源后尤为严重。其像素渲染复杂度可以达到O(mn),其中m代表总的几何体的像素总量,而n代表光源的数量

因此为了减轻这方面的运算负担,人们将渲染流程稍作修改,如下图所示:

延迟渲染中先不进行光照计算,而是在所有的缓冲区都计算完成后(法线、色彩、深度信息等),最后融合这些缓冲区结果。在这个融合过程中,可以轻易剔除掉被遮盖的物体,进行针对性的光照运算,从而避免了大量额外运算,复杂度被降低到O(m’n),其中m’代表屏幕分辨率(例如1920*1080),而n代表光照数量。由于在很多情况下m'<

然而,回顾MSAA的原理,我们可以发现MSAA之所以能节省性能是因为它仅仅处理几何体边缘相关的那些像素——计算混合完相关像素信息后覆盖到原有值上。但现在由于渲染管线被打乱,特别是由于最终的合成渲染是针对数个缓冲区执行,那些几何体原始信息已经丢失,便无法在最终渲染中判断到底哪些是边缘而哪些不是。这样一来MSAA只能对所有的像素进行采样,和SSAA已经没有什么区别了。

多重采样抗锯齿的缺失一直是延迟渲染的一个痛点,当然也有一些科学家试图引入额外的信息来辅助MSAA在这种渲染流程中判断边缘信息,但出于各种各样的原因应用并不广泛。

后处理抗锯齿的历史

虽然后处理抗锯齿在2009年Reshetov的MLAA (Morphological Anti-Aliasing)论文发表后才热门起来11,后处理抗锯齿本身并不是一个全新的概念。1983年Jules Bloomenthal在SIGGRAPH发表的文章”Edge Inference with Applications to Anti-Aliasing”中已经提及相关的方法12,而且放到今日这个方法仍旧非常可行:

那些和栅格像素排列不平行的几何边缘被采样后,会出现阶梯状锯齿。这种渲染瑕疵在2D和3D的CG中均很常出现。准确的边缘信息往往会丢失,但通过对锯齿边缘进行分析,可以估算出精度远高于原始分辨率的边缘信息。

估测出来的边缘信息可以用来对原始像素进行重新着色,从而达到平滑这些边缘的目的。相较于阶梯状的边缘,这种平滑后的边缘显然离原始边缘更为接近。

1999年,Isshiki和Kunieda提出了第一种基于这种思想的实时算法13。这种方法通过扫描图像中线和列实现,并能在硬件上运行。

总体而言,所有的纯后处理抗锯齿都包含了以下三个步骤,而不同的后处理抗锯齿主要区别就在这三个步骤的具体实现方法上:

  1. 检测图像中不连续的部分(检测边缘信息)
  2. 通过这些不连续部分的信息重建原始边缘信息
  3. 对估测边缘上的像素进行重着色

检测边缘信息

最简单也最常见的边缘检测基于图像的颜色缓冲分析。如果相邻两个像素色差大于特定的阈值,则代表它们之间不连续。这类色差计算往往基于人眼视觉模型。也就是说相较于RGB这类传统色彩模型,HSL等模型更为常用14。下图展示了横向、纵向滤波后提取出来的边缘信息15

左:原图,中:横向边缘检测,右:纵向边缘检测

为了提高边缘侦测的效率并降低误报(例如上图纹理中的“边缘信息”),边缘侦测算法往往还会参考其他类型缓冲的信息。例如储存像素Z轴信息的深度缓冲就能被用于检测边缘,但这种方法仅能辅助检测3D物体的轮廓。为了检测轮廓之外的边缘信息,还需要参考其他的缓冲。例如延迟渲染器往往会创建一个缓冲来记录每个像素的法线信息16,这样一来,邻近两个像素的法线信息也能被用作边缘检测的参考。

边缘信息的重建和混合

不同的后处理抗锯齿模式在边缘信息重建上会有些许不同,但他们往往都是对图片的横向和纵向不连续部分进行模式识别,并进一步寻找阶梯状的锯齿部分。例如下图就展示了MLAA对边缘的识别和重建方式。

MLAA边缘重建MLAA典型边缘检测类别

一旦边缘信息被重建出来,剩下的部分就相对简单了——通过衡量重建边缘和原始像素的覆盖程度进而计算颜色的混合并进行重着色。

后期处理抗锯齿的优点和缺点

后期处理抗锯齿的许多优势是基于采样的抗锯齿技术无法比拟的。对于几何失真,后期处理抗锯齿的效果能够与使用了大量采样点的基于采样抗锯齿相媲美,而前者的性能开销只是后者的几分之一。同时,后期处理抗锯齿在应用上的局限性更小。在某些情况下,比如说采用了延迟渲染后,基于采样的抗锯齿就无能为力了;而后期处理抗锯齿依然能够使用。

当然,后期处理抗锯齿有其明显的局限性:它无法解决子像素失真的问题。图2右上角线段和三角函数的支离破碎就是由子像素失真造成的,而后期处理抗锯齿对这些失真几乎没有任何帮助。这是因为后期处理抗锯齿完全依赖于对已经渲染的画面的后期分析,计算机算法不同于人类,它们没办法从分离的像素块中推测出这些像素原本想表达什么图形。比如说图中的三角函数,组成它的像素到底原本就是分离的?还是由于子像素失真导致了它们的不连续?当这样的问题出现时,两种可能的处理方式都并不理想——第一种是算法将这些像素变得模糊,以牺牲细节的代价来让锯齿变得不那么明显;第二种是让算法把这些不确定的像素扔到一边,只处理那些能够确定的边缘。

同时,后期处理抗锯齿还有可能出现误判的问题。如果画面中的某块区域被抗锯齿算法认定为需要处理的边缘(而实际上它们不是),这些区域的细节将会被损毁。当需要处理的画面中出现文字时,这一问题变得尤为明显。比较保守的算法能够减少对边缘的误判,但是这样会遗漏某些本来需要处理的边缘;相反一个激进的算法也许能够囊括更多的锯齿边缘,当然换来的代价则是误判增加。由于后期处理抗锯齿的本质是从已经生成的少量信息中推测出更多信息,这种两面性是无法避免的。

最后还有一个很重要的问题,那就是后处理抗锯齿对边缘信息的解析可能会因为一个像素之差而完全不同。因此后处理抗锯齿会恶化甚至引入更多边缘闪烁的现象17

为了说明时域下的闪烁问题,我录了几种AA的效果:

无AA

FXAA

CSAA 8x

以上三个对比均录制于1280*720的渲染分辨率,可以看出虽然FXAA尝试修复了部分锯齿,但由于光栅化后已经丢失了大量原始边缘细节,后处理抗锯齿算法也无能为力。而在动态画面中这种边缘判识不一致导致边缘闪动的现象更为明显

值得注意的是,不同于MSAA,后期处理抗锯齿对于几何失真、透明失真、甚至渲染失真的处理方式并没有什么差别:算法对于所有边缘一视同仁。一个接踵而来的问题是:屏幕上的文字也被当成图形模糊了。即使相比于FXAA,在SMAA1x中这种模糊不是那么明显。

以下的组图展示了最常见的FXAA以及SMAA1x对样例图案处理的效果和相应缺陷。一般来说,SMAA1x在目前被认为是最优的实时单采样算法。

无AAFXAA1x SMAA

以下组图展示了FXAA,SMAA1x,无AA,4xMSAA,4xSGSSAA以及理想状况对各类失真的处理情况。

理想状态无AA4x MSAA4x SGSSAA FXAASMAA

上图中值得注意的是,后处理抗锯齿算法并不单单局限于集合边缘的处理,更能处理透明失真甚至是渲染失真。不过由于所有的边缘都被相同对待,文字边缘也被抗锯齿模糊处理了(即使SMAA1x带来的劣化会小于FXAA算法)。

无论是FXAA还是SMAA1x都无法解决子像素失真的问题,但是他们在这个问题的处理方式是不同的。SMAA1x的做法更为保守,即完全不改变图中表示sin函数的白色像素点;FXAA则选择把图像中的白色像素点与周围的像素混合。至于哪一种处理方式更好,取决于具体情况和个人偏好。

客观地说,我们认为在2D几何图形测试中SMAA1x对于不同斜率的线段的处理效果要比FXAA来得更好。同时,在右下角的渲染测试中,SMAA1x输出结果的边缘更加平滑,也更接近理想情况。 这些差异是由于SMAA采用了更复杂的边缘重建与模糊手段,具体的细节可以参考2012年Jimenez et alia发表的SMAA文章18

抗锯齿技术的未来

了解了当今被广泛应用的两大类抗锯齿技术后,我们会去思考抗锯齿技术的未来。新发布的游戏平台将技术提高到新的层次,而这些新平台会采用什么样的抗锯齿技术?现有抗锯齿技术的缺点将会被如何弥补?新的硬件会带来新的抗锯齿算法吗?

一种可行的解决方案是将基于采样的抗锯齿基础和后期处理抗锯齿技术结合起来。这种新的混合抗锯齿算法在对画面进行多次采样的同时,会结合后期处理抗锯齿算法以输出最终画面。这样做的好处是显而易见的:新算法既避免了纯后期处理抗锯齿的种种缺点(比如说不能处理子像素失真和造成边缘闪烁的问题),在同样的性能折损下,对于几何失真的处理结果又比纯粹基于采样的抗锯齿算法好得多。通过将单采样后处理抗锯齿(例如FXAA)和降采样技术相结合,我们已经可以实现一种简单的混合抗锯齿。而更复杂的算法则包括了SMAA T2x, SMAA S2x, SMAA 4x,以及TXAA。本文解释了关于SMAA的一部分细节,而NVIDIA也提供了一些关于TXAA的解释。这些混合抗锯齿算法很有希望在未来得到广泛应用。

另一种可行的方案在目前还未被广泛应用:我们可以在渲染时记录额外的几何信息,以供之后的后处理抗锯齿使用。目前的实现有Geometric Post-process Anti-Aliasing (GPAA) 以及 Geometry Buffer Anti-Aliasing (GBAA)等。

最后,近期的游戏主机和未来的计算机架构已经开始共享CPU、GPU内存池,而我们可以充分利用这个优势——在近期的论文“通过使用共享内存进行异步自适应抗锯齿” 19中,Barringer和Moller描述了一种新的抗锯齿方法。这种方法中,GPU进行单采样点渲染,而CPU则在同时检测关键像素(例如边缘上的像素)并进行稀疏采样的栅格化运算。虽然这个方法需要大量重构现今的渲染架构,但前景是光明的。

(完)

——————————

后记 (密集恐惧症患者请移步)

题图出自new 3DS的移植游戏Xenoblade Chronicle 3D。在这款游戏的宣传伊始,任天堂不遗余力地宣称通过对new 3DS硬件的升级,已经让移植游戏达到了媲美家用机的视觉效果。然而在游戏过程中我认为这种论调并不确切,至少就画面而言满屏的渲染瑕疵我已经头疼不已了——由于是从Wii移植到更低分辨率,同时程序也几乎没有对画面进行任何修复和补救,你会在游戏过程中轻易发现上文所提及的各种渲染瑕疵,例如贴图移动时的像素闪烁,人物轮廓的锯齿等等……

我不止一次的幻想——倘若掌机也支持抗锯齿那么世界会有多美好?

“抗锯齿”这个词大概从最早的游戏出现开始就始终伴随在游戏玩家左右。它是人类科技落后迫不得已而有的妥协——由于计算机性能不够,不能用足够多的像素点来表现画面的细节,因而只能通过各种估测手段来让栅格化的画面尽量接近原始画面。

我虽然出生于CRT显示器的年代,应该说我家购入第一台LCD显示器的时候已经是我高一的时候了。但如今CRT时代的记忆仿佛离我是如此的遥远,以至于我已经忘了我第一次把脸贴近让人肉麻的CRT显示器看那一个个像素组成的时候是怎样的感觉。

OLYMPUS DIGITAL CAMERA

在走入LCD时代后,似乎一个像素就等价于一个红绿蓝组成的小方块。

小时候我曾经脑洞过——倘若我把显示器的像素做成圆形的,是否就不会有锯齿了呢?

虽然这个问题的答案是否定的,但也揭示了一个问题——像素排列和视觉观感有着紧密的联系。

在进入LCD时代后,人们面对的第一个问题就是文字显示的锯齿。各家公司都推出了相应的补救方案,例如微软的ClearType,通过单独利用液晶屏红绿蓝的显示来增加文字的显示精度(由于这种控制比单个像素还精细,也被成为子像素渲染)。这项技术在CRT时代几乎没有应用,因为CRT的像素并不是“小方块”。

上图:原始文字渲染;下图:ClearType技术使用后的文字渲染

而3DS的案例更为有趣,这块800×240的3D显示面板要同时兼顾左右两眼的画面呈现,会是怎样的像素排列?曾有网友指出2D模式下的锯齿感减弱了,但实际上这只不过是变更像素间距后的视觉变化。

3DS屏幕为纵向RGB排列,2D显示模式下相邻奇偶两列显示相同内容

其实通过像素排列来改善视觉观感(特别是减少锯齿)已经不是什么新鲜的话题。在智能手机蓬勃发展的今天,各种各样排列的液晶面板也如雨后春笋般涌现。例如争议很大的Pentile像素排列,由于节省成本出现了更严重的颗粒感和锯齿感……呃,不过,在DPI越来越高的今天,动不动就是5寸2K甚至4K屏的今天,已经没有多少人还能通过把眼睛贴近屏幕看到单个像素。

我突然想起来:啊!抗锯齿本身或许就是个伪命题!

或许在10年后,由于分辨率疯狂的演进,新生一代的小玩家已经不知道什么是锯齿。不过,更有可能的情况是:10年后实时抗锯齿仍是一个炙手可热的话题。我们现在所看到那些美轮美奂的游戏画面只不过是计算机科学家骗人眼球的小把戏罢了。在不久的将来,硬件性能的提升将更有可能伴随着各种前人所不敢想象的高强度CG计算,进一步反过来继续压榨自己,让我们继续在30FPS的线上挣扎。

 

 

番外小故事——3DS机能的爱与恨

3DS的机能始终是某两党争斗的热门话题之一。

PICA200这块GPU我个人认为是很有意思的一个架构设计——虽然表面上支持的特性简陋,却又不乏那些针对移动掌机设计的特殊能力。虽然被人戏称为固定管线,却有着PS/VS流水线互换的神奇单元。

最能证明PICA200性能的东西,除了脍炙人口、永远活在玩家心中的生化危机启示录外,更有代表性的应该是DMP公司在SIGGRAPH2006上所演示的3D Demo Mikage(御影)20

在这个简短的视频中,无数令人震惊的视觉特效被展现出来。要知道2006年那时候移动图形芯片的性能大概还在草履虫阶段,我觉得除了PSP那神奇的GPU外就没有什么商业产品能拿得出手了。

在这段视频中,PICA200展现出惊人的能力:

例如它支持Procedure Texture,大幅节省带宽开销

它又支持Tessellation(曲面细分),这货在DX11才开始被大炒特炒,殊不知3DS游戏中圆圆鼓鼓的小怪兽早就用了这种技术

 

 

 

它还支持软阴影

以及最后的最后,它支持立体3D模式下渲染Mikage!

至于它支不支持硬件多重采样抗锯齿,答案是——支持的

它不仅支持2×2超级采样,还支持4x Z-Buffer的多重采样21

只不过我们从来没有在实际3DS游戏中领教过www

  1. 原文请访问此处. 
  2. 不包含《微型计算机》。我中学的时候《微型计算机》曾刊载过数篇较为深入的分析,可惜限于纸媒的展示能力案例并不丰富. 
  3. 即当采样率低于原始信号频率一半时导致的信号失真现象。从不充分的采样中重建连续信号时往往会出现高频信号被重建为低频信号的问题,也被称为频率折叠. 
  4. 即将连续(无限高精度)的物体映射到有限的像素矩阵中,例如数码相机的感光元件就是对现实世界景物的一个光栅化过程. 
  5. 原文为Sample Aggregation,我个人不确定中文对应的词汇是什么,因此用采样中很常见的术语“混合”来意译. 
  6. 起源于经典的八皇后问题,即在国际象棋棋盘上怎样摆放八个皇后,使得任意一个都无法直接吃掉其他皇后. 
  7. 4x,中文念作“4倍”,指的是采样点的个数. 
  8. 事实上NVIDIA最新的Maxwell系列图形芯片已经移除对CSAA的支持,但相应的,Maxwell增加了MFAA的支持。MFAA通过在奇偶帧交替采样点从而实现2xMSAA性能折损4xMSAA画面质量的抗锯齿。需要注意的是SLI并不支持这个技术,因为SLI本身的原理就是交替帧渲染,这使得单GPU内交替帧采样后混合的做法并不可行。关于MFAA的视频演示可以参见此处. 
  9. 像素等价于小方块吗?关于像素的实质的探讨,请参见文章“像素不是小方块!”,传送门. 
  10. Kernel,也称为卷积矩阵,一般是指图像信号处理中维度有限的特殊矩阵. 
  11. A. Reshetov, ‘Morphological antialiasing’, in Proceedings of the Conference on High Performance Graphics 2009 HPG ’09, New York, NY, USA, 2009, pp. 109–116. 
  12. J. Bloomenthal, ‘Edge Inference with Applications to Antialiasing’, ACM SIGGRAPH Comput. Graph., vol. 17, no. 3, pp. 157–162, Jul. 1983. 
  13. T. Isshiki and H. Kunieda, ‘Efficient anti-aliasing algorithm for computer generated images’, in Proceedings of the 1999 IEEE International Symposium on Circuits and Systems ISCAS ’99, Orlando, FL, 1999, vol. 4, pp. 532–535. 
  14. HSL指的是色相、饱和度、明度三个色彩指标. 
  15. 即对一张2D图像分别进行横向/纵向的求差(differentiating)操作,横向求差可以获得大部分纵向边缘信息(对于斜线可求得纵向分量). 
  16. 顾名思义,即每个像素的法向量信息,一般用于光照计算. 
  17. 例如在第一帧中,某条线段被解析为边缘;但由于画面移动,在第二帧中就有可能被解析为非边缘。这样会导致边缘时有时无。这样的现象在静态画面中可能无法体现,但一旦画面动起来,边缘闪烁就可能很明显。且这种现象在低分辨率的情况下尤为明显,因为原始边缘信息被严重丢失. 
  18. J. Jimenez, J. I. Echevarria, T. Sousa, and D. Gutierrez, ‘SMAA: Enhanced Subpixel Morphological Antialiasing’, Comput. Graph. Forum, vol. 31, no. 2pt1, pp. 355–364, May 2012. 
  19. R. Barringer and T. Akenine-Möller, ‘A 4: asynchronous adaptive anti-aliasing using shared memory’, ACM Trans. Graph., vol. 32, no. 4, pp. 100:1–100:10, Jul. 2013. 
  20. 视频链接. 
  21. 来源在此处. 

你可能感兴趣的:(字体)