部分游戏抗锯齿方法介绍
0.参考
【技术美术百人计划】图形 4.4 抗锯齿概论_哔哩哔哩_bilibili
主流抗锯齿方案详解(四)SMAA - 知乎 (zhihu.com)
1.SSAA超级采样抗锯齿 (SuperSampling Anti-Aliasing)
假设最终屏幕输出的分辨率是800600,4xSSAA就会先渲染一个分辨率为16001200的buffer上,然后再直接把这个放大4倍的buffer下采样至800*600,这种做法在数学上是最完美的抗锯齿,但是劣势也很明显,光栅化和着色的计算负荷都比原来多了4倍,RenderTarget的大小也涨了4倍。
2.MSAA多重采样抗锯齿(Mulitisample Anti-Aliasing)
在默认的光栅化采样中,我们的颜色采样至像素的中点。
在MSAA的采样中,我们将采样点扩大,下面演示的是4xMSAA的采样效果
光栅化阶段记录了百分比,片元着色器阶段根据百分比上颜色
3.TAA 时间性抗锯齿 (Temporal Anti-Alising)
TAA在MSAA的基础上,将多次采样的过程分布到每一帧中去,每一帧都平均前面几帧保存下来的数据。
因此,在使用TAA时,如果画面急速变化,会产生鬼影。
详细实现原理可以看:主流抗锯齿方案详解(二)TAA - 知乎 (zhihu.com)
4.FXAA 快速近似抗锯齿
①使用边缘检测检测边缘
②使用高斯模糊等模糊算法,将获取到的边缘进行模糊
因为是使用后处理的技术,所以完全不依赖硬件支持。
5.MLAA
假设现在我们要对左边这样一张图片进行AA处理:
就需要找到中间图片中这条蓝色的重矢量化线,这就是对像素进行重矢量化(revectorization)。
MLAA处理的流程,蓝色的线表示重矢量化线
重矢量化以后,我们可以算出重矢量化线覆盖像素的面积,作为混合系数。如上图中第三张图所示,算出混合系数后,就可以将锯齿两侧的像素按照混合系数进行混合,得到第四张图中的效果。这就是整个的 MLAA 的抗锯齿原理。
从这点出发, 我们可以大致梳理出我们想要的MLAA处理的流程:
- 边缘检测, 得到每个像素的边缘,也就是锯齿边界,如下左图中绿色的线;
- 沿着锯齿边界,向两侧搜索锯齿边界的终点,也就是锯齿边界结束的位置,如下图中间图片两侧圈起来的位置;
- 根据两侧锯齿边界结束的位置,将像素矢量化, 作出一条蓝色的线,作为重矢量化线;
- 算出重矢量化线覆盖像素的面积,作为像素间的混合系数;
- 根据混合系数对像素进行混合。
详解请看 主流抗锯齿方案详解(四)SMAA - 知乎 (zhihu.com)
6.SMAA
SMAA(Enhanced Subpixel Morphological Antialiasing) 对 MLAA 的几个部分做了如下改进:
1.更准确的边界判断
对于使用颜色判断边界的情况, 很容易出现边界误判, 使得本来不应该是边界的地方被视为边界, 比如一些光照很强的地方, 虽然亮度变化快, 但是其实不应该是边界。 SMAA 中使用 Local contrast adaption 对边界进行二次判断。
SMAA中更加精确的边界判断
假设我们现在要判断某个像素和左侧像素是否构成边界。
首先使用相对亮度差的绝对值和亮度差阈值初步判断是否构成边界: 如果构成, 则需要根据周围点亮度再判断一次:
如果二次判断通过, 这个边界被保留, 如果判断不通过, 这个边界被丢弃。
2.转角保留
在某些情况下, 一些几何体的棱角可能被错误地识别为是需要AA处理的部分。
转角保留的情况处理
比如图中左上的正方形, 很可能被MLAA处理成左中的样子, 这种情况下,其实是不需要AA处理的。
那么如何分辨这样的情况呢? 解决方法是,这里沿着交叉的锯齿边界,往外再取一次边界值 (图中 e_1, e_2, e_3, e_4)。如果取不到边界,则认为是需要进行AA处理。
如果还能取到边界, 则在原来计算出的覆盖率/混合系数基础上, 再乘以一个转角系数 r (范围是0~1, 通常取0.25)。 比如上面图中橙色, 黄色, 和蓝色三条线, 分别代表三个不同转角系数下得到的新的混合系数)。
带有转角保留时的混合系数计算过程
3.对角线模式
MLAA中的模式,主要针对的是水平方向和垂直方向。然而这两种模式,处理一些斜向的边界,效果不是很好。
SMAA增加的斜线模式处理
和MLAA中使用的方法一样,我们也是使用判断两个方向的边界,算出交叉边,使用预计算的贴图信息。
SMAA斜线模式下,预计算的贴图
对角线模式应该再MLAA的水平垂直模式之前执行,如果成功找到,就不再进行水平和垂直方向的寻找。
4.更精确的边界搜索
前面在使用MLAA搜索边界时,有可能在搜索途中遗漏一些交叉边界。
比如下图中在沿着左边进行搜索时,MLAA会使用橙色的点采样,这样其实会将第一个左侧的边界遗漏,因为搜索过程中,仅判断了上边界,没有判断左边界。
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为:
当在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超采样抗锯齿