说一下 Deferred Shading MSAA那些事

以下内容纯属自己总结如有错误欢迎指正

前言 defferred shading 可以在大量光照场景中节省性能,但是不能使用混合不能使用 MSAA。

下面先梳理一下概念

MSAA 

多重采样抗锯齿 与普通采样不一样的地方是 在光栅化阶段,由硬件自己进行特定运算来多重采样最终输出平滑的颜色

wiki 定义如下

In supersample anti-aliasing, multiple locations are sampled within every pixel, and each of those samples is fully rendered and combined with the others to produce the pixel that is ultimately displayed. This is computationally expensive, because the entire rendering process must be repeated for each sample location. It is also inefficient, as aliasing is typically only noticed in some parts of the image, such as the edges, whereas supersampling is performed for every single pixel.

在超级采样中,在每一个像素的多个位置进行采样(比如 上下左右角还有中间等),并且这些采样被完全渲染,并且与其他样本结合起来生成最终的图像,这个计算很昂贵,因为这些采样位置必须都要进行处理。对于仅仅某些部分有锯齿的图片这样处理这显然不是高效的。

In multisample anti-aliasing, if any of the multi sample locations in a pixel is covered by the triangle being rendered, a shading computation must be performed for that triangle. However this calculation only needs to be performed once for the whole pixel regardless of how many sample positions are covered; the result of the shading calculation is simply applied to all of the relevant multi sample locations.

在多重采样中,如果每一个三角形的覆盖一个像素的多个位置的任意一个,一个着色就算就必须执行。然而不管多少采样位置被覆盖每一个像素仅仅执行一次着色计算。这样的着色计算结果就会被应用在所有的多重采样位置中。

In the case where only one triangle covers every multi sample location within the pixel, only one shading computation is performed, and these pixels are little more expensive (and the result is no different) than in the non-anti-aliased image. This is true of the middle of triangles, where aliasing is not an issue. (Edge detection can reduce this further by explicitly limiting the MSAA calculation to pixels whose samples involve multiple triangles, or triangles at multiple depths.) In the extreme case where each of the multi sample locations is covered by a different triangle, a different shading computation will be performed for each location and the results then combined to give the final pixel, and the result and computational expense are the same as in the equivalent supersampled image.

The shading calculation is not the only operation that must be performed on a given pixel; multisampling implementations may variously sample other operations such as visibility at different sampling levels.

对于没有锯齿的图片来说,采用三角形覆盖多个采样点,在每一个像素中仅仅计算一次也是有点昂贵的。这对于三角形中间没有锯齿问题来说肯定是的(边缘检测技术能够很大程度减少MSAA的对于三角形覆盖采样问题,或者是多个三角形具有多个深度问题(也就是说三角形不在一个平面上)在这种极端的情况下,每一个三角形的多重采样采样都会进行计算最终混合得出结果,这就会导致这个计算跟超级采样一样昂贵。

着色计算并不是必须在给定像素上执行的唯一操作;多采样实现可以对其他操作进行不同的采样,例如在不同的采样级别上的可见性。(感觉这段话理解很有问题)

优点:每一个像素着色仅仅需要计算一次        支持几何边缘抗锯齿

缺点:

alpha testing

由于alpha测试时根据物体的alpha值来剔除一些不满足alpha特定值的一些像素,由于是在像素级别进行剔除,所以对像素进行采样肯定会出现一些锯齿,即使不是在边缘也会出现。

总结一下:

其实这个多重采样描述不太准确,应该叫多个采样点(这个多个采样点是对于超级采样的多个才样点来说的)进行一次采样。而且通过光栅化三角形覆盖的像素来对一个像素进行一次计算的采样,缺点不支持alpha测试。附带一张图片进行说明如果想仔细了解的话参考 

说一下 Deferred Shading MSAA那些事

离屏MSAA渲染 

摘抄一段概念

首先我们需要生成多重采样缓冲。有两种方式可以创建多重采样缓冲,将其作为帧缓冲的附件:纹理附件和渲染缓冲附件。渲染到多重采样帧缓冲对象的过程都是自动的。只要我们在帧缓冲绑定时绘制任何东西,光栅器就会负责所有的多重采样运算。我们最终会得到一个多重采样颜色缓冲以及/或深度和模板缓冲。因为多重采样缓冲有一点特别,我们不能直接将它们的缓冲图像用于其他运算,比如在着色器中对它们进行采样。

多重采样的图像包含比普通图像更多的信息,我们所要做的是缩小或者还原(Resolve)图像。多重采样帧缓冲的还原通常是通过glBlitFramebuffer来完成,它能够将一个帧缓冲中的某个区域复制到另一个帧缓冲中,并且将多重采样缓冲还原

但如果我们想要使用多重采样帧缓冲的纹理输出来做像是后期处理这样的事情呢?我们不能直接在片段着色器中使用多重采样的纹理。但我们能做的是将多重采样缓冲位块传送到一个没有使用多重采样纹理附件的FBO中。然后用这个普通的颜色附件来做后期处理,从而达到我们的目的。然而,这也意味着我们需要生成一个新的FBO,作为中介帧缓冲对象,将多重采样缓冲还原为一个能在着色器中使用的普通2D纹理

defferred shadingng 延迟着色 区别于forward shading 的地方在于在许多光照下 我们在每个片段只会运行一次着色(所以不能使用混合,因为混合需要多个片段,而我们最终存储的只有唯一的一个位置的一个片段信息)forward shading 其实就是 每一个片段对每一个光照都会运行一次着色,defferred shaing是每个光照对每一个片段运行一次。所以,如果光照多使用defferred shading 省性能。会使用两个pass:第一个pass叫几何渲染 第二个是光照渲染。

几何渲染 得到当前场景中所有物体的信息包括世界空间位置、法线、 颜色、深度信息等到一个叫做GBuffer的东西中,由于这个信息量巨大所以需要多重渲染目标(MRT)即渲染到多张浮点纹理中。这个过程是普通的渲染流程。

第二个pass 光照渲染 这个过程就比较特殊 我们可以直接通过在几何渲染过程中得到的GBuffer缓冲信息来对光照进行计算最终输出颜色。下面这个图可以抽象的描述

说一下 Deferred Shading MSAA那些事


下面来说说为什么在defferred shading 中不能直接使用MSAA。

首先由于defferred shading 有两个pass,所以直接通过多重纹理采样来实现已经不行了。那么离屏渲染呢,咋一看可以离屏渲染需要使用MRT,而Defferred 也需要,这不是正好吗,但是离屏渲染条件(上面黄色黑背景的文字)由于我们已经有一个GBuffer了,即使我们可以再创建一个帧缓冲但是这个缓冲保存到哪里呢,即使可以保存但是多重采样也是才光栅化阶段自己处理的,没有两个buffer也不能同时在光栅化阶段处理,所以在defferred shading 中不能使用MSAA。即使能实现代价也是巨大的除非我们可以同时处理两个 fram buffer,只能等待硬件的发展了。

参考  https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing

        https://en.wikipedia.org/wiki/Multisample_anti-aliasing