MSAA renderbuffer to texture (for postprocessing)

I am slightly confused at the moment since its been a while since I did this, (I used FXAA for a long time).

But I want to have post processing with MSAA so I have the following:

Default FBO, Non multisampled.
FBO with rendertarget, Multisampled.
glBlitFramebuffer(0, 0, Width, Height, 0, 0, Width, Height, GL_COLOR_BUFFER_BIT, GL_NEAREST) from rendertarget FBO to default one.

Ok it works, but how to then post process the scene? As far as I can tell you can’t take the rendertarget and render it to a quad onto the default FBO doing postprocessing along the way.
So my idea is something like this now:

Default FBO, Non multisampled.
FBO with rendertarget, Multisampled.
FBO with texture, Non multisampled.
Draw to rendertarget FBO, blit it to texture FBO, draw its texture as a quad to the default FBO.

This works but it seems like its inefficient to do all that? also the actual result looks like it has no antialiasing.

On top of this I kinda need this to work on OpenGL 4.5 and OpenGL ES 3.0. Would very much like some input into this, thanks.

why not ? use textures as rendertargets
render your scene into these textures, and sample from these textures later when doing post processing

i dont know anything about openGL ES, but using openGL 4.5, you could use fragment shaders or compute shaders:

https://sites.google.com/site/john87connor/compute-shader/tutorial-5-2-image-kernel

Well from what I read you can’t have an FBO + texture be used with MSAA? Even apple document said that.

But that’s the only reason that multisample textures (glTexImage2DMultisample() etc) exist. There wouldn’t be much point in having them otherwise.

i tried to make a FBO with a multisampled texture attachment –> works without any problems!
an important thing is:
if you use glBlitFramebuffer(…) to copy stuff from a multisampled FBO into another (lets say the default framebuffer 0) that’s not multisampled, then both framebuffer HAVE TO have the same resolution

https://www.opengl.org/sdk/docs/man/html/glBlitFramebuffer.xhtml
// read the error section

I was looking at the glTexImage2DMultisample thing today and I found this:
ake.in . th/2013/04/02/offscreening-and-multisampling-with-opengl
“you are not able to use the result stored in the texture directly. You have to do “Blitting””.
So im still not sure how to solve my problem.

what is your problem exactly?

you know how to use a multisampled texture as framebuffer attachment:

https://sites.google.com/site/john87connor/home/tutorial-10-6-framebuffer-multisample

when you have rendered your scene into that multisampled framebuffer, render a screen-wide quad into the default framebuffer and sample from the texture using “sampler2DMS”, and do post-processing along the way
https://www.opengl.org/wiki/Sampler_(GLSL)#Sampler_types

[QUOTE=Codewyvern;1284800]I was looking at the glTexImage2DMultisample thing today and I found this:
ake.in . th/2013/04/02/offscreening-and-multisampling-with-opengl
“you are not able to use the result stored in the texture directly. You have to do “Blitting””
[/QUOTE]
This is incorrect.

Having rendered to a multisample texture, you can either blend the samples by blitting to a non-multisampled framebufer (texture, renderbuffer or default framebuffer), or you can access the multisampled texture(s) directly via a sampler2DMS. In the latter case, you’re restricted to the use of texelFetch() to retrieve individual samples; you can’t sample the texture normally (with texture() etc).

In most cases, you probably want to do the former.

Thanks john_connor and GCIlements, I was not aware of this, actually it seems I was reading out of date information.
However I am still getting a non perfect result, just trying fbo + multisampled texture -> fullscreen quad to backbuffer.

I tried something like this for now:


uniform lowp sampler2DMS Tunit0;

mediump vec4 textureMultisample(in lowp sampler2DMS sampler, in mediump vec2 texc)
{
    mediump ivec2 ipos = ivec2(floor(vec2(textureSize(sampler)) * texc));
    mediump vec4 color = vec4(0.0);
    
    for(int i = 0; i < 4; ++i)
    {
        color += texelFetch(sampler, ipos, i);
    }
    
    color /= 4.0;
    
    return color;
}

void main()
{
    
    Output = textureMultisample(Tunit0, OutTex.st);
    //Output.r = 1.0;
}

Is this ok? or something else I am missing? because result looks as if there is no multisampling, but with the blit from same fbo to backbuffer it appears fine.

Just want to say I believe I found the problem. Just using glBlitFramebuffer straight to the backbuffer gives a perfect result because nvidia driver somehow does something extra behind the scenes.
As soon as I use glBlitFramebuffer to a different FBO with a standard texture and then fullscreen quad that to the backbuffer I get a much worse result, however it is improved by giving it more samples in glRenderbufferStorageMultisample.
However it looks absolutely awful with just 4 samples. So I am not sure what nvidia is doing behind the scenes that’s giving me a super clean and crisp result. Strange.