如何在 OpenGL FBO 中使用多重采样

新手上路,请多包涵

我正在尝试为 FBO 启用多重采样和 alpha-to-coverage。使用默认帧缓冲区,我所要做的就是调用 glEnable(GL_MULTISAMPLE)glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE) 。但是,我无法使用我自己的 FBO 达到相同的效果。

我的目标: 将场景绘制到 FBO,就像将场景绘制到具有上述属性的默认帧缓冲区一样。从那里我希望能够将图像用作未来通过着色器的纹理。

这有效:用于制作没有多重采样/alpha 覆盖、1 个颜色附件、1 个深度附件的 FBO 的代码:

 // Generate the color attachment
glGenTextures(1,&defaultColorAttachment0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,defaultColorAttachment0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,screenWidth,screenHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);

// Bind the texture to the FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, defaultColorAttachment0,0);

// Generate the depth attachment
glGenRenderbuffers(1,&defaultDepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, defaultDepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, screenWidth, screenHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, defaultDepthBuffer);

这行不通。尝试制作多采样 FBO 的代码:

 // Generate the color attachment
glGenTextures(1,&defaultColorAttachment0);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, defaultColorAttachment0);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA, screenWidth, screenHeight, GL_FALSE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, defaultColorAttachment0,0);

// Generate the depth attachment
glGenRenderbuffers(1,&defaultDepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, defaultDepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, screenWidth, screenHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, defaultDepthBuffer);

我已经尝试过浏览 OpenGL wiki,尽管它不完整(各种未完成的标题使它看起来不专业)。 glGetError 从不抱怨。我已经尝试过解决这个问题,但我要么得到黑屏,要么得到一个满是垃圾像素的屏幕。

主要问题: 为了让多重采样和 alpha-to-coverage 与 FBO 一起工作,我需要考虑/更改哪些内容以及在何处(FBO 创建、纹理、着色器)?

原文由 GraphicsMuncher 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 864
1 个回答

您需要分配一个多重采样深度缓冲区才能正常工作,并为其提供与颜色缓冲区相同数量的样本。换句话说,您应该调用 glRenderbufferStorageMultisample (...) 而不是 glRenderbufferStorage (...)

您的 FBO 应该没有按照现在的分配方式进行完整性检查。调用 glCheckFramebufferStatus (...) 应该返回 GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 因为您的深度缓冲区 正好1 个 样本,而您的颜色缓冲区附件有 4 个


由于您还在此 FBO 中使用了多采样纹理附件,因此您应该了解在 GLSL 着色器中采样单采样纹理与多采样纹理之间的差异。

多重采样纹理具有特殊的采样器统一类型( 例如 sampler2DMS ),您必须使用 texelFetch (...) 通过其整数(非标准化)纹理坐标和样本索引显式获取纹理中的每个样本.这也意味着它们不能被过滤或映射。

在这种情况下,您可能不想要多重采样纹理,您可能想要使用 glBlitFramebuffer (...) 将 MSAA 解析为单采样 FBO。如果您这样做,您可以在着色器中读取抗锯齿结果,而不必获取每个样本并自己实现抗锯齿。

原文由 Andon M. Coleman 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题