MSAA那些事

高品质游戏中锯齿是一个讨厌的东西,形成锯齿的原因有很多种比如因为光栅化导致的锯齿,再比如因为Alpha test导致的锯齿,锯齿形成的原因多多少少都和smaple有关。有一种抗锯齿的方法叫做SSAA(超级采样抗锯齿),这个名字真的很吊,专制各种不服,专制各种锯齿。但是使用SSAA不仅会增加帧缓存以及深度/模板缓存的大小,还会增加PS的计算量,总之是一个很费性能的操作。于是它的小弟MSAA出现了,它和SSAA相比性能有所优化,但是实力不如它的大哥SSAA,MSAA有两个不足点,第一修复的效果不如SSAA,第二貌似和延迟渲染不合。

无论是SSAA还是MSAA原理都是扩大分辨率,让像素变的更小,如果像素足够小,小到人眼无法察觉,那么锯齿也就彻底被打败了。

我们就拿4x抗锯齿说说,如果我们屏幕的分辨率是1024*1024,那么为了抗锯齿,我们需要申请更大的帧缓存以及深度/模板缓存,他们的分辨率就是2048*2048。帧缓存和深度/模板缓存这对好基友,它们的分辨率必须一致。

这样之前的每一个像素都被分配了四个子像素,SSAA很暴力,每个子像素都会进行PS计算,然后降采样取平均值,生成最终的像素颜色。

MSAA为了提高性能,它为每一个子像素分配一位掩码,代表他们最终会不会被渲染到帧缓中。子像素需要通过很多考验,首先是光栅化阶段是否在图元中,其次是深度/模板测试。通过测试的子像素才能复制中心像素的颜色。因此MSAA只计算中心像素的颜色。MSAA之所以提高了性能是因为大大降低了PS的计算量(一个像素只计算一次)。如果四个子像素都通过了考验,那么最终像素的颜色其实就是中心像素的颜色,如果只有一个点通过,那么颜色就是中心像素的1/4。在网上看到有人说Alpha to Coverage能够实现无序半透明,这个看的我一头雾水。思考之后其实这就是一个方向性的误导,先来看一下为什么会用Alpha to Coverage。

我们通常用一个面片代表一片叶子,然后通过alpha test测试哪些地方是透明的如上图,但是这种效果透明边缘处会有锯齿。

为了获得更柔和的边缘效果,我们把alpha test改成了alpha blend,这样边缘处就柔和多了。但是使用alpha blend就需要渲染排序,性能又成问题了。

于是为了兼容效果和性能,Alpha to Coverage出现了,每个像素都被分配了一个dither mask,这个dither mask是根据alpha值来确定的,比如alpha为1那么dither mask就是1111,如果alpha为0那么dither mask为0000,如果为0.5那么dither mask为0011,这个中间的值由硬件决定。于是dither mask和coverage bit进行与操作最终生成coverage bit。但是Alpha to Coverage有一个问题0-1之间的范围明显要高于dither mask能表达的范围(只有四个区间值)。所以会出现如下的问题:

提高抗锯齿的倍数可以改善效果但是这个真的值得么?DX11可以在FS阶段对dither mask进行扰序,从而提高效果表现。

Alpha to Coverage从头到尾也没有使用alpha blend所以就与渲染顺序无关了,它只是根据alpha值确定dither mask,然后确定coverage bit,然后在降采样的时候稀释颜色从而达到边缘柔和的效果。

 

MSAA与延迟渲染水火不容 

首先我们要知道MSAA是硬件支持的抗锯齿,dx9时代MRT不支持抗锯齿。而对于延迟渲染来说,几何体的光栅化都是在生成GBuffer的时候进行的,也就是说子像素都没有机会进行上面说的测试,怎么做MSAA,因此dx9时代是硬件不支持。后来dx10.1MRT支持了MSAA,但是有个限制就是每个RT需要同样的sample,存储basecolor的RT没问题,深度和法线的RT这么做问题就大了,一个像素的深度是0.5,然后做个抗锯齿深度就变成0.25,这是不能接受的。于是延迟渲染要想做MSAA就需要先开启多重采样渲染basecolor的GB,然后再关闭多重采样渲染其他的RT,这种性能的消耗还不如直接开启SSAA了。所以dx10.1以后的延迟渲染不是不能做MSAA,而是这么做没有意义,因此MSAA就这样与延迟渲染插肩而过。推荐两篇文章,一篇是介绍MSAA原理,一篇是说MSAA和延迟渲染为什么冲突,他们讲解的都很详细而且有图,我在这里只是说一下自己的理解,就不做搬运工了。

https://blog.csdn.net/jxw167/article/details/56014355

https://zhuanlan.zhihu.com/p/135444145

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值