跳转至

抗锯齿简介

本文是科普类文章,简化了细节,可能会有失严谨。

引言

任何一张照片都是对真实世界的采样,它将连续的世界离散成一个个小方格(马赛克),而一个方格被赋予了一个颜色。

如果这个方格太大,大到我们肉眼可见,一条直线的渲染结果就会呈现“锯齿状”。而“抗锯齿”的目的即是减少“锯齿感”,减少肉眼可见的锯齿(格子变小点),让人感受到连续与平滑(与旁边的像素做一个渐变),让人感受到舒适。

因此,在屏幕大小不变的情况下增加分辨率,是最粗暴的 抗锯齿 方法。这属于 物理层面 的方法,通过 提高硬件性能 所达到的。而我们关心的是软件层面的魔法。

Tips: 屏幕大小不变,格子数量变多 => 单个格子就小了,锯齿感就差

抗锯齿

抗锯齿(anti-aliasing,简称AA),也被译为边缘柔化、消除混叠、抗图像折叠有损,反走样等等。

它是一种消除显示器输出的画面中图物边缘出现凹凸锯齿的技术,那些凹凸的锯齿通常因为高分辨率的信号以低分辨率表示或无法准确运算出 3D 图形坐标定位时所导致的图形混叠(aliasing)而产生的,抗锯齿技术能有效地解决这些问题。

方法 简述
SSAA Super sample anti-aliasing, 超采样抗锯齿
对三维场景做 “超采样” ,以此达到抗锯齿的目的
原来片元着色器需要执行1920x1080次,SSAA需要执行3840x2160次,最后再将结果合并成1920x1080
MSAA MultiSampling Antialising,多采样抗锯齿,是SSAA的改良版
MSAA只需执行1920x1080次片元着色器,只不过在一个片元着色器当中,计算出N个采样点有M个在三角形内,最后将颜色乘上N/M个权重
现代显卡都有在GPU中实现算法,无需开发人员处理。因为它只是多计算了“N次点是否在三角形内”,所以比称为“多采样”,比“超”更轻量
CSAA Coverage Sampling Anti-Aliasing, 覆盖采样抗锯齿
HRAA High Resolution Anti-Aliasing, 高分辨率抗锯齿,也称Quincunx方法
CFAA Custom Filter Anti-Aliasing,可编程过滤抗锯齿
MLAA Morphological Anti-Aliasing, 形态抗锯齿
FXAA FXAA,Fast Approximate Anti-Aliasing,快速近似抗锯齿
FXAA是对渲染结果做图像处理。大致思路是识别出边界,然后对边界像素与周边像素做一个平滑过渡
TAA Temporal Anti-Aliasing,帧间抗锯齿
TAA的基础是帧间相关性,它复用历史帧,将N个历史帧与当前帧做加权平滑,从而达到抗锯齿平滑的效果
MFAA Multi-Frame Sampled Anti-Aliasing, 多帧采样抗锯齿

SSAA

SSAA(super sample anti-aliasing),超采样抗锯齿。

简单而言

  1. SSAA与提高分辨率的方式一样,也是非常粗暴与原始
  2. 例如,当前屏幕是1920x1080分辨率的,而2x2的SSAA会将场景渲染至3840x2160分辨率的结果,最后将渲染结果合并成1920x1080,再展现到屏幕上

具体而言:对三维场景做超采样,达到抗锯齿的目的。

  1. 在一个像素中取N个采样点(不一定是均匀分布)
  2. 再对每个采样点分别着色计算
  3. 最后将N个采样点的颜色取平均值,作为此像素点的颜色值

SSAA

优点:方法粗暴简单,效果十分客观。
缺点:开销是原来的N倍,适用于2D渲染。因为3D场景数据量大,SSAA不适用

  • 原先只需要执行1920x1080次片元着色器,2x2的SSAA要执行3840x2160次片元着色器,开销很大

MSAA

MSAA,MultiSampling Antialising,多采样抗锯齿,是SSAA的改良版。现代所有GPU都在硬件上实现了这个算法,无需开发者实现。

简单而言

  1. 对于1920x1080分辨率、2x2的SSAA,它的性能损耗大4倍。因为一个像素要着色2x2次,即需要执行1920x1080x2x2次片元着色器
  2. 而对于1920x1080分辨率、2x2的MSAA不一样,它着色的像素个数没有改变,还是和原先一样(如图b),只需要着色1920x1080个像素
  3. 只不过,它在片元着色器中,对每个像素计算一个权重(具体如何计算,看下文)
  4. 将权重与渲染结果相乘,即达到了模糊原始图像的效果,从而达到“抗锯齿”的目的(如图c)

a原始三角形b渲染结果cMSAA结果

【如何计算每个像素的权重呢?】简单而言

  • 当一个片元着色器着色器完之后,再做一个后处理:
  • 例如,取2x2个采样点,GPU计算出有3个在三角形内,那么最终结果 = 3/4 * 片元颜色
  • 因此,它实际上只是多(Multi)考虑了几个点,而非真正超(Super)采样了。消耗少,因此被称为MSAA

【一些效果图】

FXAA

FXAA,Fast Approximate Anti-Aliasing,快速近似抗锯齿。

简而言之

  1. FXAA其实是一种图像的后期处理技术,它先光栅化出图片,然后对渲染结果进行后期处理
  2. 它通过一些图像匹配的方法,将渲染结果中的边界(锯齿都是在边界上)找到
  3. 找到边界以后,与周围的像素做一个平滑

优点:快速有效。
缺点:纹理细节会被模糊。

效果图:

TAA

TAA,Temporal Anti-Aliasing,帧间抗锯齿。

TAA的基础是“帧间相关性”(frame-to-frame coherence)

  1. 视频,或者动画,本质上是在时间维度上的采样,它将某个时刻采样成一张图片。如果采样的速度很快,比如1s中拍25张,那足够骗过人的眼睛,达到动画的效果
  2. 一秒快速轮播25张图片,单拎出来两张,你会发现他们的差异很小。这就是帧间相关性,因为每一帧之间的时间间隔很小,导致相邻帧之间其实非常相似,变化很小

简而言之:TAA的核心思想即是利用帧间相关性,复用之前的帧图像(历史帧),拿它们与当前帧做加权混合,从而达到平滑锯齿的效果,减少突变

  • 需要注意的是,每帧中像素的采样点需要做抖动,否则相邻帧相同位置上的颜色没多大变化,就达不到“抗锯齿”的目的

如何理解TAA?

  1. 以2x2 SSAA举例,对于每一帧每个像素需着色4次,这无疑加大了计算量
  2. 而前面介绍了帧间相关性,我们无需对一个像素着色4次,我们只需拿此帧前面的3帧,拿来做加权平滑,不就达到了2x2 SSAA的效果。如此,我们没有额外着色3次,反而达到了SSAA的效果
  3. 因此,TAA即是将N个采样点的计算量**分摊到了其他帧**上,而不用在某帧的时候再计算,以此降低计算量

参考文章

  1. GAMES101反走样笔记
  2. 图形学中的抗锯齿方法简谈
  3. 《Real-Time Rendering 3rd》 提炼总结