1

I am having problems using explicit multisampling when using multiple rendering targets in OpenGL.

I have 4 render targets (Position, Diffuse + opacity, Normal, Specular + exponent) that are rendered to during the initial geometry pass.

These are all non multisampled textures attached to a framebuffer object, and then set as the render targets using glDrawBuffers(). This works fine, and I can then sample these textures later to get the information needed for lighting calculations. Lovely.

Without multisampled textures. MRT works fine.

I now want to try to remove some of the aliasing I am getting, so I started to implement explicit MSAA using multisampled textures. However, when I use multisampled textures as the render targets instead, only the first render target seems to be drawn to and the rest remain blank.

With multisampled textures. Only rendered to the first drawbuffer.

Other than changing how the textures are setup, bound and read in the shaders I haven't changed any other code.

Multisampled textures are attached to the framebuffer object using this code:

for (unsigned int i = 0; i < textureCount; ++i)
{
    // Generate texture
    GLuint texture;
    glGenTextures(1, &texture);    

    // Bind multisample texture
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
    glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, msaaSamples, GL_RGBA, width, height, false);

    // Set params
    glTexParameterf(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    // Attach to frame buffer
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D_MULTISAMPLE, texture, 0);

    // Unbind
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
}

Multisampled depth/stencil texture is attached as well.

glGenTextures(1, &depth);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, depth);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, msaaSamples, GL_DEPTH24_STENCIL8, width, height, false);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, depth, 0);

The framebuffer is then bound and draw buffers set

glBindFramebuffer(GL_FRAMEBUFFER, fbo);
GLuint attachments[4] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
glDrawBuffers(4,  attachments);

I then draw the geometry as usual. However, when inspecting with apitrace it is clear that only the first color attachment is being drawn into. This is not the case when I use regular (non-multisampled textures).

All 4 draw buffers are definetly still being set however.

4 draw buffers set.

sangwe11
  • 123
  • 6
  • Please post the relevant parts of the code. It is impossible to help without that. – derhass Apr 10 '15 at 18:16
  • Added what code could be relevant, and also 2 pictures to highlight the issue. – sangwe11 Apr 10 '15 at 19:16
  • Do you have a multisamples depth/stencil attachment, too? – derhass Apr 10 '15 at 20:11
  • 1
    What's also suspicious is the line `GLuint attachments[2] = { GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4 }`. It should be array size 4, not 2, The attachment count should also begin with 0. – derhass Apr 10 '15 at 20:16
  • If changing "attachments[2]" to "attachments[4]" doesn't fix it, then calling glCheckFramebufferStatus after binding the framebuffer might help with diagnosing the problem. – jhoffman0x Apr 11 '15 at 02:38
  • Sorry attachments[2] was a typo, in the code the array size is 4. The frame buffer does have multisampled depth/stencil attachment as well, I can post the code used to attach that if needed. glCheckFramebufferStatus returns GL_FRAMEBUFFER_COMPLETE, so it isn't an issue with the framebuffer. The issue is more I cannot seem to draw to multiple render targets when the framebuffer has multisample textures instead of non-multisampled textures. – sangwe11 Apr 11 '15 at 17:38
  • Well, those screenshots hint that in your multisampled case, there is only one color attachment. I don't know why this is. Are you sure you end up with the correct FBO at all? – derhass Apr 11 '15 at 17:42
  • Looking using apitrace, when I bind the framebuffer it shows up that it has 4 colour attachments, 1 depth and 1 stencil. This seems correct as it should have 4 textures for attributes, and then a depth / stencil attachment. I agree however it looks as if only one colour attachment is being used. I am definetly calling glDrawBuffers() with the correct attachments as they show up in the apitrace parameter list shown in the screenshot above. – sangwe11 Apr 11 '15 at 17:53

1 Answers1

0

glTexParameterf cannot be used with GL_TEXTURE_2D_MULTISAMPLE.

Apart from this I would set the 'fixedsamplelocations'-param of glTexImage2DMultisample to true just to be on the safe side regarding hardware compatibility.

And I recommend to use a sized format like GL_RGBA8 instead of GL_RGBA (don't know how you managed to get GL_RGBA32F as listed in the first image with the unsized GL_RGBA enum...).

MaximumFPS
  • 141
  • 1
  • 4