less than 1 minute read

前言

上文中介绍了实时渲染中的采样理论基础。根据采样定理,锯齿问题的本质是采样精度不足,解决方案也是两种思路:

  1. 提高采样率
  2. 先对输入信号进行低通滤波,去除高频部分,避免混叠(Aliasing)

本文主要介绍笔者在实际开发过程中对于锯齿问题的使用场景理解,本文并不打算详细地介绍每一种具体的抗锯齿算法(但是会列举出一些不错的参考资料), 而是计划更专注于各种抗锯齿算法的对比和使用分析。希望作为日常抗锯齿问题的一个简单手册。

实时渲染中存在很多采样过程,比如光栅化渲染管线中,将显示媒介用有限的分辨率来表示,本身就是采样的过程;在使用纹理时,也会涉及到对纹理数据的采样。 在这些采样过程中,会出现混叠现象而最终带来各种各样的锯齿,包括高光锯齿,高频边缘的jaggies等等。按照上文提到的解决混叠问题的两种思路, 我们首先对各种常见的抗锯齿算法做一些总结,然后针对具体的锯齿问题做一些分析。

抗锯齿算法/方法 思路 描述
SSAA 提高采样率 理论中的算法,性价比极低,不适合实时渲染,只有极少数不计消耗的3A游戏才会用,比如使命召唤11
MSAA 提高采样率 集成到GPU硬件中的抗锯齿,多次采样,但是光照计算只有一次,多次采样会增加带宽,而center sampling也会造成一些闪烁问题,可以用centroid sampling
TAA 提高采样率 将多次采样分布到时间维度上,达到提高采样率的效果,在渲染流程中的位置值得考究,有闪烁问题,有动态物体,半透明物体的时候需要特殊处理
SpecularAA 低通滤波 在光照计算的时候,对于曲率变化大的pixel位置使用滤波后的NDF,以减小高光锯齿,算法依赖差分计算得到的曲率精度
FXAA 图像后处理(低通滤波) 将抗锯齿问题作为图像后处理,性能友好但效果一般,处理高光锯齿的效果有限,一般与其他抗锯齿算法结合
SMAA 图像后处理 将抗锯齿问题作为图像后处理,性能友好但效果一般,处理高光锯齿的效果有限,一般与其他抗锯齿算法结合
MipMap 低通滤波 纹理图片本身包含高频信息的一种处理方法
Centroid Sampling 低通滤波 针对MSAA center sampling出现 artifact的一种处理方式,centroid sampling也有自身的缺点,会导致fragment shader中差分计算结果出错,因为使用的不是像素中心点的数据

纹理采样的锯齿

当贴图数据中有高频信息,而贴图区域在渲染窗口中覆盖的区域很小时,由于采样精度不足,会产生摩尔纹。

Figure 1. 摩尔纹示例

  • 提高采样率:如果要提高采样率,那么需要增加贴图覆盖区域的像素密度,比如提高渲染分辨率,SSAA等。
  • 低通滤波:一般遇到这种贴图锯齿问题,更常见的还是通过Mipmap来对原始贴图进行低通滤波,GPU在采样纹理的时候,会自动根据贴图覆盖区域的大小与额贴图本身的大小 来调整采样贴图的mip level。
Mipmap
Figure 2: Mipmap
来源: 维基百科

一般来讲,通过图形API对加载后的贴图生成 Mipmap的时候,会直接采用与周围像素加权平均的办法,也就是滤波核是矩形窗函数,上一篇文章中我们介绍过 矩形窗函数的傅里叶变换是 Sinc 函数,并不是很好的低通滤波器,会漏高频信息。所以当贴图中确实有很多高频量的时候(比如突变的颜色或者亮度),需要采用 更好的低通滤波核。

高精度模型带来的锯齿

高精度模型的三角面片数量较大,尤其在模型曲率变化大的地方,需要庞大数量的三角网格来表示这些高曲率变化的曲面。这时显示设备的单个像素覆盖不止一个三角面片, 而每个像素是使用像素中心点的法线数据进行着色计算的。这种情况下采样精度不足的问题就出现了。

  • 提高采样率:SSAA, MSAA, TAA, SSAA是暴力提高采样频率,进行多次光照计算再取平均,一般超采样会有多重不同的pattern,MSAA同SSAA一样需要进行多次采样,但只会进行一次光照计算,TAA会将多次采样分布在不同帧上,比如4x的超采样需要在4帧结束之后才能完成。
  • 低通滤波:Specular AA
  • 修改模型:在可能的情况下修改模型,通过增大倒角,减面等方式人为去除模型中的高频部分。抗锯齿算法总会消耗计算资源,修改模型是最一本万利的做法。
Figure 3: Super Sampling Patterns
来源: 维基百科
Figure 4: Specular AA Filtering
来源: https://jcgt.org/published/0010/02/02/paper-lowres.pdf

后处理抗锯齿

后处理抗锯齿一般是用图像后处理的方法,这时候我们认为管线的渲染结果是固定的,对于已经出现的锯齿进行一定程度的消除。一般来说这类方法性能友好,但是效果相比其他方法也会有很大折扣。

  • FXAA
  • SMAA

超分辨率抗锯齿

目前有DLSS,AMD FSR等许多图像超分算法,可以通过先超分在降采样的方式进行一定的抗锯齿,注意这和SSAA具有基本一致的原理,并且也同样是应当极力避免的方案。

锯齿纹理处理工作流

  1. 通过抓帧等调试方法判断锯齿问题的来源:贴图,高模,MSAA Center Sampling etc.
  2. 如果是资产本身带有高频,尽量通过修改资产的方式去除锯齿,如贴图的Mipmap, 修改高模的高曲率处的Mesh
  3. 后处理抗锯齿算法能够满足的情况下选择后处理抗锯齿:性能最友好
  4. MSAA Center Sampling 导致的采样问题而出现的亮点,可以尝试使用 MSAA Centroid Sampling,但要注意这会影响着色算法中任何计算差分的数据的正确性,如果算法中并没有计算差分,可以忽略这个影响
  5. TAA 在静态下效果不错,但可能会抖动,动态场景(动态相机,动态物体),尤其是动态透明物体存在时,TAA的表现可能会不尽如人意
  6. SSAA最直观有效(因为就是简单地提高着色分辨率再降采样)但是非常消耗,是性价比最低的抗锯齿算法,鲜有人使用。

相关抗锯齿算法链接

本博文内容为作者原创,转载请注明出处并附上原文链接,感谢支持与理解。

Tags:

Categories:

Updated: