Opengl 具有多颜色附件的多采样帧缓冲区的分辨率

Opengl 具有多颜色附件的多采样帧缓冲区的分辨率,opengl,framebuffer,multisampling,deferred-rendering,deferred-shading,Opengl,Framebuffer,Multisampling,Deferred Rendering,Deferred Shading,尝试在延迟着色的基础上实现抗锯齿,我尝试使用多采样渲染缓冲区,然后使用缓冲区blit过程解析采样 与延迟着色中的传统方式一样,我使用专用着色器渲染场景,并发出3种颜色输出: 职位 常态 漫反射和镜面反射 然后,这些将用于照明计算过程,最终生成场景纹理 场景纹理使用简单化的着色器渲染到全屏四边形上的屏幕 正如您可能猜到的,在渲染到屏幕时,屏幕上的MSAA不会应用于场景纹理的内容: 因此,为了实现抗锯齿,我在步骤1)中选择使用多采样渲染缓冲区,并为分辨率引入了额外的步骤1.1)。当然,多重采样仅

尝试在延迟着色的基础上实现抗锯齿,我尝试使用多采样渲染缓冲区,然后使用缓冲区blit过程解析采样

  • 与延迟着色中的传统方式一样,我使用专用着色器渲染场景,并发出3种颜色输出:

    • 职位
    • 常态
    • 漫反射和镜面反射
  • 然后,这些将用于照明计算过程,最终生成场景纹理

  • 场景纹理使用简单化的着色器渲染到全屏四边形上的屏幕

  • 正如您可能猜到的,在渲染到屏幕时,屏幕上的MSAA不会应用于场景纹理的内容: 因此,为了实现抗锯齿,我在步骤1)中选择使用多采样渲染缓冲区,并为分辨率引入了额外的步骤1.1)。当然,多重采样仅对颜色贴图是必要的/有用的,而不是其他两个贴图

    我的问题是,显然,具有多个渲染缓冲区/颜色附件的帧缓冲区只能为相同类型的附件定义;这意味着,如果一个附件是多重抽样的,那么所有其他附件都必须是多重抽样的

    这对于分辨率期间的位置和法线缓冲区来说是一个问题,因为几何体和照明会由于抗锯齿而受到影响

    • 我对帧缓冲区附件的理解有效吗
    • 是否有办法解决此问题,以便在漫反射和镜面反射贴图上仍具有多重采样,但不影响其他贴图
    上面的代码示例的结果是,被照亮对象的边缘显示了不适当的暗/黑或亮/白像素的瑕疵,可能是因为它们的位置和/或法线在此过程中发生了改变

    这对于分辨率期间的位置和法线缓冲区来说是一个问题,因为几何体和照明会由于抗锯齿而受到影响

    应该是的

    在获取漫反射/镜面反射颜色时,位置和法线不使用多重采样在逻辑上是不相干的。记住什么是多重采样:每个像素有多个采样,来自重叠三角形的不同数据可能写入同一像素中的不同采样。因此,可以在同一像素中使用两个或多个三角形的漫反射/镜面反射颜色。但这也意味着你也应该拥有与这些亚像素颜色相关的位置和法线。否则你的照明通行证就没有意义了;对于没有生成位置和法线值的颜色,应该使用位置和法线值


    使用延迟渲染进行适当的多重采样是昂贵的。使其工作的唯一方法是对所有内容进行多重采样,然后在每个采样级别上执行照明过程计算。由于与超级采样相比,多重采样的大部分性能增益并不是针对每个采样进行计算,因此您只能在几何体过程中获得多重采样(而不是超级采样)的好处,而不是在照明过程中


    这就是为什么人们在使用延迟渲染时尽量避免多重采样。这就是为什么像FXAA这样的伪抗锯齿技术以及其他任何存在的技术。

    “唯一可行的方法是对所有内容进行多重采样,然后在每个采样级别上执行照明过程计算”。从技术上讲,这不是唯一的办法。如果这个特定的gbuffer像素中的所有样本都来自gbuffer本身的同一个原语,那么实际上可以存储信息,并在照明过程中使用该原语,仅对像素的每个样本执行此操作,但情况并非如此,如下所示。标记已回答,因为我理解您的观点@Nicolas,但是,我仍然要说以下几句话:对我来说,消除混叠不是一个技术/物理上真实的原则(指你的评论,我应该像颜色一样使用多重采样几何体),相反,它只是为了通过模拟平滑度来蒙蔽眼睛-记住这一点,它仍然是有意义的,将谨慎/准确(非多次采样)的几何体应用于边缘(多次采样)上稍微不相干/错误的着色。特别是因为这些像素在它们周围的环境中大部分是褪色的。在你的最后一点上,我同意NSAA,FSAA似乎是下一个要尝试的东西,我已经开始尝试,只是到目前为止没有太多成功@德哈斯:我觉得你提出了一个有趣的建议,但我不能百分之百肯定我能接受。我会再仔细考虑一下:)@Smoove:我是说FXAA。但是你不应该把抗锯齿看作是虚构的。它是一个真实的东西,通过模拟到数字信号处理在数学上定义。它不是“愚弄眼睛”或“模拟平滑”的东西;这是一个真实的概念。@Nicolas Bolas yes FXAA谢谢你-我其实知道你的意思,但我自己还是重复了这个错误:D
        // Create the frame buffer for deferred shading: 3 color attachments and a depth buffer
        glGenFramebuffers(1, &gBuffer);
        glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        {
            // - Position color buffer
            glGenRenderbuffers(1, &gPosition);
            glBindRenderbuffer(GL_RENDERBUFFER, gPosition);
            glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA16F, w, h);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, gPosition);
    
            // - Normal color buffer
            glGenRenderbuffers(1, &gNormal);
            glBindRenderbuffer(GL_RENDERBUFFER, gNormal);
            glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA16F, w, h);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, gNormal);
    
            // - Color + specular color buffer
            glGenRenderbuffers(1, &gColorSpec);
            glBindRenderbuffer(GL_RENDERBUFFER, gColorSpec);
            glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA, w, h);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, gColorSpec);
    
            unsigned int attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
            glDrawBuffers(3, attachments);
    
            // - Generate the depth buffer for rendering
            glGenRenderbuffers(1, &sceneDepth);
            glBindRenderbuffer(GL_RENDERBUFFER, sceneDepth);
            glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h);
            glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_DEPTH_COMPONENT, w, h);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, sceneDepth);
        }
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    
        // Create a frame buffer with 3 attachments for sample resolution
        glGenFramebuffers(1, &gFrameRes);
        glBindFramebuffer(GL_FRAMEBUFFER, gFrameRes);
        {
            glGenTextures(1, &gPositionRes);
            glBindTexture(GL_TEXTURE_2D, gPositionRes);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, w, h, 0, GL_RGB, GL_FLOAT, nullptr);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPositionRes, 0);
    
            glGenTextures(1, &gNormalRes);
            glBindTexture(GL_TEXTURE_2D, gNormalRes);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, w, h, 0, GL_RGBA, GL_FLOAT, nullptr);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gNormalRes, 0);
    
            glGenTextures(1, &gColorSpecRes);
            glBindTexture(GL_TEXTURE_2D, gColorSpecRes);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gColorSpecRes, 0);
        }
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    
    
        // ...
        //
        // Once the scene is rendered, resolve:
        glBindFramebuffer(GL_READ_FRAMEBUFFER, gBuffer);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gFrameRes);
        glReadBuffer(GL_COLOR_ATTACHMENT0);
        glDrawBuffer(GL_COLOR_ATTACHMENT0);
        glBlitFramebuffer(0, 0, sw, sh, 0, 0, sw, sh, GL_COLOR_BUFFER_BIT, GL_LINEAR);
        glReadBuffer(GL_COLOR_ATTACHMENT1);
        glDrawBuffer(GL_COLOR_ATTACHMENT1);
        glBlitFramebuffer(0, 0, sw, sh, 0, 0, sw, sh, GL_COLOR_BUFFER_BIT, GL_LINEAR);
        glReadBuffer(GL_COLOR_ATTACHMENT2);
        glDrawBuffer(GL_COLOR_ATTACHMENT2);
        glBlitFramebuffer(0, 0, sw, sh, 0, 0, sw, sh, GL_COLOR_BUFFER_BIT, GL_LINEAR);
        glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);