前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >走样与反走样

走样与反走样

作者头像
Peter Lu
发布2022-12-22 14:54:18
8420
发布2022-12-22 14:54:18
举报
文章被收录于专栏:LETLET

当初我对爱情的想象,如今全都走了样。--- 《走样》

写这篇文章,我是认真的,专门听了《走样》这首歌,寻找一下写作的感觉。俗话说,做人和唱歌一样,歌一定要唱完,人不可以做一半。所以,文章也不能只有一个开头。

什么是走样(aliasing)

片面报道(走样)

现实生活中,走样(Aliasing)无处不在,本文开头的歌词描述了爱情在时间域下的走样,而上图则反映了空间域下的走样。所谓的走样,就是当我们掌握的信息(采样)不充分时而会错了意。下面我们通过一个简单的函数理解采样的过程,以及在这个过程中如何产生了走样。为什么要用正弦函数举例呢,因为傅里叶告诉我们,任何函数都可以通过正余弦函数来拟合。

正弦函数如上图所示,假设我们对正弦函数采样并基于采样点重建该函数,至少需要两个采样点(蓝色),这两个采样如上图所示,假设我们对正弦函数采样并基于采样点重建该函数,至少需要两个采样点(蓝色),这两个采样点告诉了该函数的极值(Y方向,Amplitude,振幅)以及周期长度(X方向,Period)。正弦函数的周期,则采样周期(采样点的间隔)。因为频率和周期互为倒数:,我们可得如下推论(为函数最大频率):

该条件称为奈奎斯特-香农(Nyquist-Shannon)采样定理,该定理告诉我们,当我们对一个函数进行采样时,为了保证采样点能够真实还原该函数,采样频率大于被采样信号最高频率的两倍。备注,本文不涉及该定理的数学推导(引入狄拉克梳状(Dirac Comb)函数,该函数在时域和频域都是脉冲状)。

走样

上图说明了当我们的采样频率小于函数的最大频率时,基于蓝色采样点的重建结果并不能真实的还原红色的函数,我们称之为混叠现象。现实生活中也有很多直观的例子,如下图,假设车轮旋转一周需要4秒,当我们每隔2秒看一眼(采样),我们可以判断红色车轴变化了,但无法判断到底是顺时针还是逆时针。因此,当车轮从启动到高速旋转时,基于肉眼采样,我们的大脑会有这样的一个经历:正转(正确),静止(临界),倒转(误判)。

车轮

反走样(antialiasing)技术

渲染中的走样

在图形渲染中,走样也是不可避免的。如上图,每个像素代表了一个采样点,不同区域像素大小(DPI)的不同等同于不同的采样频率,这影响了不同区域的渲染效果。

SSAA图示

SSAA(Supersampling AA)

因此,我们也创建了各类反走样技术。最简单粗暴的方式就是增加采样点。如上图:

  • 一个像素分解为个亚像素,图中
  • 采样每个亚像素的颜色
  • 基于采样点的颜色值,计算该像素的颜色

这种反走样技术称为SSAA,采样点的位置依赖于随机算法,可以是uniform或stratification,而最终的颜色则依赖不同的低通滤波函数(为什么是低通?)。

走样VS反走样

上图是没有AA和16倍SSAA的对比,可以看到树叶,蓝色墙面部分SSAA更为平滑。SSAA的通俗理解就是生成一张超大的图,然后挤压到对应屏幕的大小,让肉眼无法分辨单独像素,从而提升画面的细腻感。但代价也是巨大的,意味着计算量成倍的增加,性能和效果之间是线性关系。

MSAA(Multisample AA)

MSAA图示

从渲染质量的角度,SSAA是最完美的反走样算法,但渲染定律“只要渲染的图形看起来是对的,那就是对的”,于是我们总是想方设法的偷工减料,期待着蒙混过关。上图是MSAA的示意图:

  • 一个像素拆分为个采样点,图示中
  • 计算该三角形覆盖的采样覆盖率
  • 着色阶段,该像素的颜色乘以覆盖率

相比SSAA,MSAA的最大不同在于着色阶段,SSAA需要计算每个采样点的着色信息,比如采样点的颜色,对应渲染管线中靠后的片元阶段,整体计算量都需要成倍增长,而MSAA仅需要判断三角形的几何信息(覆盖率),对应渲染管线靠前的栅格化阶段,后续阶段只计算像素(而非采样点)的着色信息,大大节省了计算量,比如OpenGL和WebGL 2中,提供了gl.renderbufferStorageMultisamplegl.blitFramebuffer方法实现multiple sample的硬件加速能力。

MSAA图示

那么,代价是什么?主要来自两个角度。首先,MSAA没有增加着色阶段的采样,对于着色阶段产生的走样问题无法改善。比如上图中的树叶,通常树叶效果依赖半透明效果,而栅格化阶段的覆盖率无法获取这些半透明信息,因此,OpenGL提供了gl.SAMPLE_ALPHA_TO_COVERAGE参数,实现将alpha传递给coverage mask。同时,OpenGL中也提供了gl_SampleID变量,一旦在片元着色器中使用该变量,则着色阶段对应每个采样点而非像素,MSAA则退化为SSAA。半透明问题可以绕过去,但不同采样点引起的深度检测不准确等问题,高质量的MSAA需要考虑诸多的细节问题。而对于Nanite这种像素级三角形而言,硬件光栅化的价值降低,计算量主要集中在着色阶段,MSAA不适用于这类的场景。

其次,MSAA毕竟增加了采样点,不可避免的增加了计算量和内存占用量,最为诟病的是和延迟渲染(Deferred Shading)中,栅格化和着色阶段的解耦加剧了该问题,尽管有算法可以做到延迟渲染中支持MSAA,但迄今为止,几乎所有渲染引擎中,延迟渲染仍不支持MSAA,比如UE;硬件加速带来的跨平台兼容性问题,不同主机,不同引擎(OpenGL,Vulkan等)的API带来的开发难度。

无论是SSAA还是MSAA,反走样的核心思路是增加采样点,这些采样点会影响到渲染管线的各个阶段,带来的性能开销和存储压力,以及硬件加速和兼容性问题,人们退而求其次,是否可以在后处理阶段执行反走样,这样反走样和渲染管线解耦,降低问题的复杂度。

FXAA(Fast approXimate AA)

之前的反走样技术都是基于图形信息(几何&材质)执行反走样算法,然后获取最终的图像信息。如果把反走样限制在后处理阶段,此时我们已经丢失了图形信息(几何&材质),只能基于图像信息模拟图形信息,然后设计适合的反走样算法。

后处理中的反走样

通常,一个合理的假设是(屏幕)空间中多数区域是连续的(不需要反走样),而采样定理告诉我们,图像的高频来源于边缘区域,这是反走样的重点区域。如上图所示,这类算法的基本步骤是:

  • 后处理阶段的图像信息
  • 基于图像的边缘提取
  • 模拟边缘的几何信息
  • 基于几何信息的混合算法(Blend)

FXAA 1.0版本(2009)的大概思路基本一致,首先,每个像素计算上下左右四个临近像素间的对比度,超过一定阈值,则认为当前像素为边缘像素(图(2));然后基于左右/上下亮度差确定该边缘是水平或竖直,确定蓝线斜率(图(3));根据斜率以及对比度进行混合,实现渐变效果(图(4))。

FXAA 3.11

FXAA 1.0版本的不足是图像容易变糊,对此,FXAA推出了3.11版本(2011)。Quality版本提升了几何模拟的准确度,计算边缘像素的左右边界的长度以及边界的三种形状:线型,角点(凹凸两种),更准确的几何信息可以获取更好的混合因子,抑制变糊问题。计算边界长度需要更多的采样计算,Console版本简化了采样数,来适应游戏主机的需求。

FXAA的特点是简单,只需要一个Pass就能实现抗锯齿,无论是CPU还是GPU,都是一个轻量的后处理反走样技术。FXAA 3.11算得上是目前应用最广泛的后处理反走样技术。

SMAA(Enhanced Subpixel Morphological AA)

SMAA

SMAA基于MLAA,可以认为是增强版的MLAA。如上图,其流程和FXAA完全相同,计算边缘,获取混合因子,最后得到反走样结果。最大的区别是SMAA是一个3-pass的后处理反走样技术,每一步单独一个pass。

SMAA提取边缘

SMAA的第1个pass比较简单,基于颜色或其他属性,提取边缘。

SMAA获取边界信息

SMAA最大的改进在于第2个pass,计算混合因子。在这一步中,首先,通过bilinear的方式,高效的计算边界的左右距离,以及边界的类型(图右1~4)。

SMAA计算覆盖率

其次,已知(x轴),(y轴),边界的类型对应其中一种类型,纹理是预计算,直接获取对应的覆盖率。

SMAA计算覆盖率

最后是第3个pass,根据覆盖率进行混合,获取反走样后的图像。

反走样对比

SMAA可以作为FXAA的替代方案,并且和MSAA并不冲突,因此,也可以通过MSAA+SMAA提供更好的反走样效果。上图是在Cesium中不同反走样效果的对比。

在实现SMAA中,我们需要注意后处理中的纹理格式是RGB,而导入和导出的图像纹理是RGBA格式,不同格式之间的转化。同时,在计算边界类型时需要借助search texture,过滤方式要选择GL_NEAREST

其它

反走样的技术很多,推荐资料 Filtering Approaches for Real-Time Anti-Aliasing[1]

TAA,基于时序的反走样技术,通常需要考虑Velocity变量,如果两帧变化较大,则丢弃上一帧的采样点,避免ghost的问题。

DLSS,Nvidia基于深度学习的反走样技术,了解不多,多种反走样技术结合深度学习的思路,没有用过。

基于SDF的反走样技术,通过获取该像素距离边界的距离,作为混合因子,在字体渲染中广泛应用。

着色中的反走样

本文中介绍的反走样技术,除了SSAA外,其他的反走样技术主要是处理几何边缘区域采样不足产生的走样,并没有涉及到着色阶段的走样问题。着色阶段因为涉及到渲染方程,采样问题更为复杂。

A Survey of Nonlinear Prefiltering Methods for Efficient and Accurate Surface Shading

当一个像素包含的mesh内容非常复杂时,如上图,可能包含深绿色的树林,浅绿色的草丛以及黄色的沙地区域,每个区域都有不同的法线,高度以及材质,相互之间也会有影响。这种复杂情况下,单纯增加采样点如同SSAA,巨大的计算量难以满足实时要求。

AGAA

AGAA(Aggregate G-Buffer AA)的思路时把多个采样点,通过Prefilter方式合并成N个采样点,然后只需要计算N个采样点的着色加权,得到最终的渲染结果。这里的关键不同属性的合并方式的选择,比如法线的合并是非线性的,而Texture多数是线性的,但可见性等是不连续的,如何保证Prefilter的准确度,会决定最终的着色结果。

SSAA VS AGAA

上图是UE中采用AGAA和SSAA的对比效果。

总结

本文解释了走样的原理,以及渲染中常用的反走样技术。目前的反走样技术处于后处理阶段,通常仅考虑几何边界的覆盖情况来计算混合因子,实现反走样的效果。

本文重点解释了SSAA,MSAA,FXAA和SMAA四种,也介绍了AGAA这个基于着色的反走样技术,以及相关技术在实现中的一些注意事项,优劣对比。

参考资料

[1]

Filtering Approaches for Real-Time Anti-Aliasing: https://iryoku.com/aacourse/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-07-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 LET 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是走样(aliasing)
  • 反走样(antialiasing)技术
    • SSAA(Supersampling AA)
      • MSAA(Multisample AA)
        • FXAA(Fast approXimate AA)
          • SMAA(Enhanced Subpixel Morphological AA)
            • 其它
              • 着色中的反走样
              • 总结
                • 参考资料
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档