部分游戏抗锯齿方法介绍

0.参考

【技术美术百人计划】图形 4.4 抗锯齿概论_哔哩哔哩_bilibili

主流抗锯齿方案详解(四)SMAA - 知乎 (zhihu.com)

1.SSAA超级采样抗锯齿 (SuperSampling Anti-Aliasing)

假设最终屏幕输出的分辨率是800600,4xSSAA就会先渲染一个分辨率为16001200的buffer上,然后再直接把这个放大4倍的buffer下采样至800*600,这种做法在数学上是最完美的抗锯齿,但是劣势也很明显,光栅化和着色的计算负荷都比原来多了4倍,RenderTarget的大小也涨了4倍。

img

2.MSAA多重采样抗锯齿(Mulitisample Anti-Aliasing)

在默认的光栅化采样中,我们的颜色采样至像素的中点。

img

在MSAA的采样中,我们将采样点扩大,下面演示的是4xMSAA的采样效果

img

img

光栅化阶段记录了百分比,片元着色器阶段根据百分比上颜色

img

3.TAA 时间性抗锯齿 (Temporal Anti-Alising)

TAA在MSAA的基础上,将多次采样的过程分布到每一帧中去,每一帧都平均前面几帧保存下来的数据。

img

因此,在使用TAA时,如果画面急速变化,会产生鬼影。

详细实现原理可以看:主流抗锯齿方案详解(二)TAA - 知乎 (zhihu.com)

4.FXAA 快速近似抗锯齿

①使用边缘检测检测边缘

img

②使用高斯模糊等模糊算法,将获取到的边缘进行模糊

img

因为是使用后处理的技术,所以完全不依赖硬件支持。

5.MLAA

假设现在我们要对左边这样一张图片进行AA处理:

就需要找到中间图片中这条蓝色的重矢量化线,这就是对像素进行重矢量化(revectorization)

img

MLAA处理的流程,蓝色的线表示重矢量化线

重矢量化以后,我们可以算出重矢量化线覆盖像素的面积,作为混合系数。如上图中第三张图所示,算出混合系数后,就可以将锯齿两侧的像素按照混合系数进行混合,得到第四张图中的效果。这就是整个的 MLAA 的抗锯齿原理。

从这点出发, 我们可以大致梳理出我们想要的MLAA处理的流程:

  1. 边缘检测, 得到每个像素的边缘,也就是锯齿边界,如下左图中绿色的线;
  2. 沿着锯齿边界,向两侧搜索锯齿边界的终点,也就是锯齿边界结束的位置,如下图中间图片两侧圈起来的位置;
  3. 根据两侧锯齿边界结束的位置,将像素矢量化, 作出一条蓝色的线,作为重矢量化线;
  4. 算出重矢量化线覆盖像素的面积,作为像素间的混合系数;
  5. 根据混合系数对像素进行混合。

img

详解请看 主流抗锯齿方案详解(四)SMAA - 知乎 (zhihu.com)

6.SMAA

SMAA(Enhanced Subpixel Morphological Antialiasing) 对 MLAA 的几个部分做了如下改进:

1.更准确的边界判断

对于使用颜色判断边界的情况, 很容易出现边界误判, 使得本来不应该是边界的地方被视为边界, 比如一些光照很强的地方, 虽然亮度变化快, 但是其实不应该是边界。 SMAA 中使用 Local contrast adaption 对边界进行二次判断。

img

SMAA中更加精确的边界判断

假设我们现在要判断某个像素和左侧像素是否构成边界。

首先使用相对亮度差的绝对值和亮度差阈值初步判断是否构成边界:image-20231120181705199 如果构成, 则需要根据周围点亮度再判断一次:

image-20231120181649909

如果二次判断通过, 这个边界被保留, 如果判断不通过, 这个边界被丢弃。

2.转角保留

在某些情况下, 一些几何体的棱角可能被错误地识别为是需要AA处理的部分。

img

转角保留的情况处理

比如图中左上的正方形, 很可能被MLAA处理成左中的样子, 这种情况下,其实是不需要AA处理的。

那么如何分辨这样的情况呢? 解决方法是,这里沿着交叉的锯齿边界,往外再取一次边界值 (图中 e_1, e_2, e_3, e_4)。如果取不到边界,则认为是需要进行AA处理。

如果还能取到边界, 则在原来计算出的覆盖率/混合系数基础上, 再乘以一个转角系数 r (范围是0~1, 通常取0.25)。 比如上面图中橙色, 黄色, 和蓝色三条线, 分别代表三个不同转角系数下得到的新的混合系数)。

img

带有转角保留时的混合系数计算过程

3.对角线模式

MLAA中的模式,主要针对的是水平方向和垂直方向。然而这两种模式,处理一些斜向的边界,效果不是很好。

img

SMAA增加的斜线模式处理

和MLAA中使用的方法一样,我们也是使用判断两个方向的边界,算出交叉边,使用预计算的贴图信息。

img

SMAA斜线模式下,预计算的贴图

对角线模式应该再MLAA的水平垂直模式之前执行,如果成功找到,就不再进行水平和垂直方向的寻找。

4.更精确的边界搜索

前面在使用MLAA搜索边界时,有可能在搜索途中遗漏一些交叉边界。

比如下图中在沿着左边进行搜索时,MLAA会使用橙色的点采样,这样其实会将第一个左侧的边界遗漏,因为搜索过程中,仅判断了上边界,没有判断左边界。

img

MLAA中可能会出现错误的边界搜索方式

SMAA将双线性采样的技巧进一步发挥, 在右下图中的采样点采样, 在xy轴上取不同的偏移量, 这样就可以做到一次采样, 根据得到的值同时判断出周围4个点的边界信息。

如下图, 将采样点放置在2x2像素中心, 向左偏移1/3, 向下偏移1/6。 这样,设周围四个像素点的值(取值为0或1)为C_1、C_2、C_3、C_4,在R处采样时, 可求得四个像素点的采样的权重S_1、S_2、S_3、S_4和采样时得到最终结果C为:

image-20231120181629251

img

当在R处进行双线性过滤采样时,周围四个像素点,可能的值是0或1,共可构成16种不同的组合,每种组合下,我们采样得到的值都是唯一的

因为边界值只能是0或者1,所以周围的四个像素点的值,共有16种可能的组合,每种组合下,双线性采样得到的值都是唯一的。读者可自行计算验证,这里不再列出具体的数值。

这样我们既提高了搜索边界的速度,还提高了搜索边界的质量,可谓是一举两得。

SMAA是 MLAA(Morphological Antialiasing) 的一个加强版

可以看出,SMAA 对锯齿的处理非常精细,得到的效果也非常好,可以说是基于后处理方法,处理抗锯齿的极限。如果要得到更好的抗锯齿效果,还可以和其他的抗锯齿方式进行结合。不过和 FXAA 一样,SMAA 也没有次像素的特征,在高频区域移动摄影机时可能会出现闪烁。

SMAA的需要三次 Pass,相对于 FXAA 性能消耗略大,对于现在的PC来可以说是非常轻松。而在手机上运行时,因为手机上切换 RenderTarget 会有比较大的开销,因此手机上还是使用 FXAA 的比较多,虽然画面会模糊一些,但是属于可以接受的范围。

6.抗锯齿性能排序

根据他们的原理,我们可以很好的为他们进行排序

①FXAA快速近似抗锯齿

②TAA时间抗锯齿

③MSAA多重采样抗锯齿

④SSAA超采样抗锯齿

最后修改:2023 年 11 月 20 日
如果觉得我的文章对你有用,请随意赞赏