OpenGL - 如何绘制到多重采样帧缓冲区,然后将结果用作普通纹理?

时间:2017-03-18 18:25:18

标签: opengl framebuffer antialiasing multisampling

我正在开发一个小型的gamedev库。该库的一个元素是Canvas(屏幕外绘图区域),它通过OpenGL帧缓冲实现。到目前为止,一切都很好,我生成一个纹理,将它附加到一个帧缓冲区,渲染到它,然后使用framebuffer的纹理作为Texture2D。

现在,我想在我的库中添加抗锯齿,所以我希望能够在Canvas上设置多重采样。现在我很困惑,因为我发现你需要改变着色器以使用多重采样纹理等等。

那么,我该怎样做才能为我的帧缓冲区启用多重采样,以便最大限度地减少更改库的其余代码?如果可能的话,我想将渲染结果用作常规的Texture2D。

1 个答案:

答案 0 :(得分:3)

只是为了确保没有混淆。你不仅可以创建一个x倍大的纹理,然后希望过滤器能够发挥魔力。因为GL_LINEAR等只有averages the four texels closest to the center of the pixel being textured

要创建多重采样纹理,您需要使用glTexImage2DMultisample()(自3.2以来在核心中可用)。你可以这样设置它。

glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, width, height, false);

它应该是不言自明的,因为samples是多重采样纹理中的样本量。您也可以根据需要更改internalformat

要将纹理附加到帧缓冲区,您同样使用glFramebufferTexture2D()。但是,不要将textarget设置为GL_TEXTURE_2D,而是将其设置为GL_TEXTURE_2D_MULTISAMPLE

glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex, 0);

请记得检查帧缓冲区的状态。

在着色器中,您还必须使用sampler2DMS才能访问多重采样纹理。但请注意,与常规纹理相比,多重采样纹理的工作方式完全不同。如果你想从纹理中读取,你必须使用texelFetch()

因此,如果您想从多重采样纹理中进行采样,则不能使用texture(),但必须使用texelFetch()之类的内容。

uniform int texSamples;
uniform sampler2DMS tex;

vec4 textureMultisample(sampler2DMS sampler, ivec2 coord)
{
    vec4 color = vec4(0.0);

    for (int i = 0; i < texSamples; i++)
        color += texelFetch(sampler, coord, i);

    color /= float(texSamples);

    return color;
}

请注意texelFetch()没有采用标准化坐标,您可以通过以下方式来规避这一点:

vec2 uv = vec2(0.5, 0.5); // normalized coordinates
ivec2 texSize = textureSize(tex, 0);
ivec2 texCoord = ivec2(uv * texSize);
vec4 color = textureMultisample(tex, texCoord);

如果你想要显示清晰的消除锯齿效果,那么你必须在屏幕上显示它。

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glDrawBuffer(GL_BACK);
glBlitFramebuffer(0, 0, src_width, src_height, 0, 0, dst_width, dst_height, GL_COLOR_BUFFER_BIT, GL_LINEAR);

如果您需要多重采样深度缓冲区,请查看glRenderbufferStorageMultisample()

同时确保glEnable(GL_MULTISAMPLE)。但是今天大多数驱动程序默认启用它。

最后但同样重要的是,这里有一些与您可能感兴趣的多重采样相关的Stack Overflow / Exchange问​​题。