C++ 如何在多采样纹理中渲染颜色和深度?

C++ 如何在多采样纹理中渲染颜色和深度?,c++,opengl,framebuffer,antialiasing,multisampling,C++,Opengl,Framebuffer,Antialiasing,Multisampling,为了实现“深度剥离”,我将OpenGL场景渲染到一系列帧缓冲区中,每个帧缓冲区都配有rgba颜色纹理和深度纹理。如果我不关心抗锯齿。如果我这样做,那么似乎正确的做法是启用GL\u多重采样,并使用GL\u纹理2D\u多重采样,而不是GL\u纹理2D。但我不知道还有哪些电话需要更换 特别是,我应该如何调整帧缓冲区结构以使用glTexImage2DMultisample而不是glTexImage2D 我是否需要将对glFramebufferTexture2D的调用更改为使用GL\u TEXTURE\u

为了实现“深度剥离”,我将OpenGL场景渲染到一系列帧缓冲区中,每个帧缓冲区都配有rgba颜色纹理和深度纹理。如果我不关心抗锯齿。如果我这样做,那么似乎正确的做法是启用
GL\u多重采样
,并使用
GL\u纹理2D\u多重采样
,而不是
GL\u纹理2D
。但我不知道还有哪些电话需要更换

特别是,我应该如何调整帧缓冲区结构以使用
glTexImage2DMultisample
而不是
glTexImage2D

我是否需要将对
glFramebufferTexture2D
的调用更改为使用
GL\u TEXTURE\u 2D\u MULTISAMPLE
而不是
GL\u TEXTURE\u 2D

如果在纹理中渲染颜色和深度,是否需要调用
glRenderbufferStorageMultisample

最后,除了设置帧缓冲区渲染到的纹理之外,我还需要做一些
glBlit*


在这个主题上有很多相关的问题,但我发现的解决方案似乎没有一个指向一个规范的教程或将所有这些结合在一起的清晰示例。

虽然我只使用了带渲染缓冲层的多采样FBO渲染,而不是纹理,但以下是我的理解

我是否需要将对
glFramebufferTexture2D
的调用更改为使用
GL\u TEXTURE\u 2D\u MULTISAMPLE
而不是
GL\u TEXTURE\u 2D

不,你只需要这些。使用
glTexImage2DMultisample()
创建纹理,然后使用
GL\u texture\u 2D\u MULTISAMPLE
作为
glFramebufferTexture2D()
的第三个参数将其附加。唯一的限制是级别(第5个参数)必须为0

如果在纹理中渲染颜色和深度,是否需要调用
glRenderbufferStorageMultisample

对。如果将深度缓冲区附加到同一FBO,则需要使用具有与颜色缓冲区相同采样数的多采样渲染缓冲区。因此,您可以使用
glRenderbufferStorageMultisample()
创建深度渲染缓冲区,并传入用于颜色缓冲区的相同样本数

最后,除了设置帧缓冲区渲染到的纹理之外,我还需要做一些
glBlit*

不用于渲染到帧缓冲区。渲染完成后,有两个选项:

  • 可以将多采样纹理下采样(解析)为常规纹理,然后将常规纹理用于后续渲染。要解析多采样纹理,可以使用
    glBlitFramebuffer()
    ,其中多采样纹理附加到
    GL\u READ\u FRAMEBUFFER
    ,常规纹理附加到
    GL\u DRAW\u FRAMEBUFFER

  • 可以将“多采样”纹理用于后续渲染。对于着色器代码中的采样器,需要使用
    sampler2DMS
    类型以及相应的采样函数


  • 对于选项1,我真的看不到使用多采样纹理的好理由。您也可以使用多示例renderbuffer,它稍微更易于使用,并且至少应该同样有效。为此,您可以为颜色附件创建一个renderbuffer,并使用
    glRenderbufferStorageMultisample()
    分配它,这非常类似于深度缓冲区所需的内容。

    我认为通常,如果您正在进行深度剥离或延迟着色并渲染到FBO,则不需要使用多采样AA。我可能是错的,所以我不想提交正式的答案,但我认为一般来说,如果您选择这些类型的路线,常见的解决方案是将基于图像/像素的AA(如FXAA、MLAA或SMAA)作为手动后处理。最近在游戏中这样做变得非常普遍,我认为这是因为使用了这些涉及到渲染到屏幕外纹理的技术后,游戏需要这样做。至于渲染屏幕外绘制的内容,有一个
    glBlitFramebuffer
    函数用于此目的,但是,只需设置正交投影,识别MV矩阵并使用FBO颜色附着纹理渲染纹理四边形,就可以获得更大的灵活性。它将允许您在片段着色器中处理结果,并进行后处理,如AA或延迟着色。谢谢,Ike。我试着渲染到一个大得多的缓冲区中,然后用平滑的方法进行下采样,但是像1倍厚的锐利线条这样的东西并不像屏幕上正确的多采样那样容易或完美。更不用说速度非常慢。根据您的质量/速度/工作量的需要,有很多基于图像的AA算法可以在着色器中运行,包括那些不需要额外视频内存(不需要渲染到比通常更大的缓冲区)的算法。例如,本文展示了FXAA方法及其外观:这可能也有一定的相关性——它讨论了如何使用屏幕外多采样:。它展示了如何构造多采样FBO。值得注意的是,本文提到如何使用
    glBlitFramebuffer
    解析来自多采样目标的图像,以及如何使用frag着色器中的
    sampler2DMS
    从多采样纹理访问纹理。我不清楚的一件事是,是否可以让一个多样本FBO同时包含深度和颜色附件。我们可能需要两张通行证。谢谢,雷托。我在尝试中丢失了
    2dms
    。我试试这个。