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

时间:2013-12-09 23:14:46

标签: c++ opengl fbo multisampling

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

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

此作品:制作没有多重采样/ alpha-to-coverage,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从不抱怨。我试过搞乱这个,但我得到一个黑屏或一个充满垃圾像素的屏幕。

主要问题:我需要考虑/更改哪些内容(FBO创建,纹理,着色器)才能使多重采样和alpha-to-coverage与FBO一起使用?< / p>

2 个答案:

答案 0 :(得分:27)

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

你的FBO应该没有完整性检查它现在分配的方式。对glCheckFramebufferStatus (...)的调用应该返回GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,因为您的深度缓冲区完全 1 样本且您的颜色缓冲区附件 4


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

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

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

答案 1 :(得分:0)

这是一个与接受的答案一起使用的工作示例。这是 LearnopenGL 教程中三角形示例的修改示例,用于将 MSAA 自定义帧缓冲区绘制到四边形,然后绘制到默认帧缓冲区(屏幕):

CALL apoc.export.cypher.query('MATCH (a:Object)-[r]-(b:Object) WHERE NOT a:Type1 AND NOT a:Type2 RETURN *', '/data/csv_destination/export.cypher',{format:'cypher-shell'});

感谢来自 LearnOpenGL 评论部分的 Matt Stone 提供工作代码。