我正在尝试为FBO启用多重采样和Alpha到覆盖。使用默认的帧缓冲区,我所要做的就是调用glEnable(GL_MULTISAMPLE)
和glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE)
。然而,我无法用我自己的FBO达到同样的效果。
**我的目标:**将场景绘制到FBO,就像绘制到具有上述属性的默认帧缓冲区一样。从那里,我希望能够使用该图像作为纹理的未来通过着色器。
这行得通:制作无多采样/Alpha-to-Coverage的FBO代码,1个颜色附件,1个深度附件:
// 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维基,尽管它不完整(各种未完成的标题让它看起来不专业)。glGetError
从不抱怨。我试着摆弄这个,但我要么得到了一个黑屏,要么得到了一个充满垃圾像素的屏幕。
**主要问题:**我需要考虑/更改哪些内容以及在哪里(FBO创建、纹理、着色器)才能使用FBO进行多重采样和Alpha到覆盖?
3条答案
按热度按时间9w11ddsr1#
需要分配多采样深度缓冲区才能正常工作,并为其提供与颜色缓冲区相同数量的采样数。换句话说,您应该调用
glRenderbufferStorageMultisample (...)
而不是glRenderbufferStorage (...)
。你的FBO应该没有通过现在分配的完整性检查。对
glCheckFramebufferStatus (...)
的调用应该返回GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
,因为您的深度缓冲区具有*正好1样本,而您的颜色缓冲区附件具有4。由于您还在该FBO中使用多采样纹理附件,因此应注意对GLSL着色器中的单采样纹理采样和多采样纹理采样之间的差异。
多采样纹理具有特殊的采样器统一类型(例如
sampler2DMS
),您必须使用texelFetch (...)
通过其整数(非规格化)纹理像素坐标和采样索引显式获取纹理中的每个采样。这也意味着它们不能被过滤或MIPMap。在这种情况下,您可能不需要多采样纹理,您可能希望使用
glBlitFramebuffer (...)
将MSAA解析为单采样FBO。如果这样做,则可以在着色器中读取抗锯齿结果,而不必获取每个采样并自己实现抗锯齿。cl25kdpy2#
这里有一个符合公认答案的工作例子。这是LearnOpenGL教程中三角形示例的修改示例,用于将MSAA自定义帧缓冲区绘制到四边形,然后绘制到默认帧缓冲区(屏幕):
感谢LearnOpenGL评论区的Matt Stone提供的工作代码。
bgtovc5b3#
除了jackw11111的回答之外,我还想用python测试这个样例代码。随信附上的是我在LearnOpenGL的评论中显然是由Matt Stone翻译成Python代码的近1:1翻译。在Ubuntu和MacOS上进行了测试。