I'm having trouble with the msaa depth buffer resolving to a depth texture. I create my glTexImage2d for both my color texture and my depth texture and bind them to the "resolve" ( non-msaa ) framebuffer. Then I create and bind another framebuffer and create my multisampled renderbuffers ( both color and depth ). I know to get my color texture information from the multisampled renderbuffer I just blit with the write buffer being my color texture framebuffer and the read buffer being my msaa-framebuffer. My question is how do I blit my multisampled depth buffer to my depth texture.
You would do this the same way you would do for the color buffer, only you would use GL_DEPTH_BUFFER_BIT and make sure you use GL_NEAREST for the filter mode. If you want linear filtering on a depth/stencil buffer, for whatever reason, you can actually do this in GLSL if you use a depth texture (of course this still remains invalid for MSAA textures) - but it is invalid to do this using glBlitFramebuffer (...).
You do not have to do any of the glReadBuffer (...) nonsense like you do when you want to select an individual color buffer, glBlitFramebuffer (...) will copy the depth buffer from the bound GL_READ_FRAMEBUFFER to the bound GL_DRAW_FRAMEBUFFER.
Related
I want to achieve a post process outline effect on some actors in my game and I want the outline be occluded by other actors closer to the camera. To do so I planed to render the elements that should be outline in an FBO and an outline shader. To discard the pixel that are occluded I want to use the depth buffer of the default framebuffer.
I read and searched but I didn't find how to properly use the default framebuffer depth buffer in another framebuffer or how to copy or anyway to use the default depth buffer informations on an fbo.
How can I achieve it?
I read and searched but I didn't find how to properly use the default framebuffer depth buffer in another framebuffer
Unfortunately, there is no way in OpenGL to do that.
or how to copy or anyway to use the default depth buffer informations on an fbo.
That is quite easy. Just create an FBO with a appropriate depth attachment (no matter if texture or renderbuffer), and blit the default depth buffer to it:
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, your_target_fbo);
glBlitFramebuffer(0,0,width,height,0,0,width,height,GL_DEPTH_BUFFER_BIT, GL_NEAREST);
However, since you do some post-processing anyway, it might be a good option to render the intial scene into an FBO and re-use the same depth buffer in different FBOs.
Unfortunately, it is not possible to attach the default depth-buffer to a FBO or to read it from a shader.
You can copy the default framebuffer into a renderbuffer (or a framebuffer attached texturem, see glBlitFramebuffer), but this could be relatively slow.
Another option is to render the complete scene first to a FBO (color + depth), then use the outline shader to read from this FBO, combine the result with the outline calculation and write the final result to the default framebuffer.
I need to read the depth value of a pixel of a multisampled FBO. I tried using glBlitFramebuffer (drawing to a non-multisampled FBO and then calling glReadPixels), but glBlitFramebuffer gives me an error(invalid framebuffer operation).
Shaders can not read data from framebuffer, they can pass data only forward by rendering pipeline. But for post-processing it is needed to read rendered image.
I'm going to resolve this as following: 1) create a texture with size of viewport; 2) render image to the texture normally; 3) render the texture to framebuffer passing it through post-processing shader.
Am I doing right? Are there more effective ways to do post-processing?
That is indeed the usual way to do post-processing ! Render to texture by binding an FBO for your first pass, then use that texture as the input of your post-process shader after unbinding your FBO (i.e. returning to the default frame buffer).
Here's the situation: I have a texture containing some depth values. I want to render some geometry using that texture as the depth buffer, but I want the color to be written to the normal framebuffer (i.e., the window's framebuffer).
How do I do this? I tried creating an FBO and only binding a depth texture to it (GL_DEPTH_COMPONENT) but that didn't work; none of the colors showed up.
No you can't. The FBO you are rendering to may be either a main framebuffer or an off-screen one. You can't mix them in any way.
Instead, I would suggest you to render to a color renderbuffer and then do a simple blitting operation into the main framebuffer.
Edit-1.
Alternatively, if you already have depth in the main FB, you can first blit your depth and then render to a main FB, thus saving video memory on the additional color renderbuffer.
P.S. Blitting is done via glBlitFramebuffer. In order to make it work you should setup GL_READ_FRAMEBUFFER, GL_DRAW_FRAMEBUFFER and glDrawBuffer() for each of them.
I have a frame buffer object in an OpenGL program with multiple colour attachments, and am trying to upgrade it to a multisampled FBO.
As I understand it, a multisampled FBO is only able to use render buffers, specifically ones created using glRenderbufferStorageMultisampleEXT. If I want something rendered to this FBO in a texture, I need to create a second FBO with textures for its attachments, then blit the multisampled FBO to the regular FBO using glBlitFramebufferEXT.
The very, very sparse examples I've seen assume a single colour attachment. What do I do when I want to blit multiple colour attachments?
From the EXT_framebuffer_blit specification
12) Should we add support for multiple ReadBuffers, so that
multiple color buffers may be copied with a single call to BlitFramebuffer?
Resolved: No, we considered this but the behavior is awkward
to define and the functionality is of limited use.
From the arb_framebuffer_object specification (which superscedes the EXT_ version)
When the color buffer is transferred, values are taken from the read
buffer of the read framebuffer and written to each of the draw buffers
of the draw framebuffer, just as with CopyPixels.
So... It's pretty clear that you resolve only from a single color buffer per blit.
To do multiple ones, you need to do a Blit for each buffer, changing your READ_BUFFER for each buffer you want to blit, and select the corresponding draw buffer of the draw framebuffer.
You can create a new Fbo and assign the renderbuffer in slot 1 to it at slot 0. Then bind for reading and blit from that to your final destination Fbx.
i.e. An Fbo can be created purely for binding an existing renderbuffer that was written to by another Fbo. An Fbo doesn't actually own the buffers that are connected to it so multiple Fbx can be bound to the same textures/renderbuffers(though not at the same time).
// Render to Fbo0
Fbo0 : [ColorBuffer0, ColorBuffer1, DethBuffer]
// Bind another fbo with ColorBuffer1 at slot 0 for reading
Fbo1 : [ColorBuffer1]
// blit Fbo0 ColorBuffer0 > Fbo2 Texture0
Fbo0 : [ColorBuffer0, ColorBuffer1, DethBuffer] => Fbo2 : [Texture0]
//blit Fbo1 ColorBuffer1 (bound at slot0) > Fbo3 Texture1 (bound at slot0)
Fbo1 : [ColorBuffer1] => Fbo3 : [Texture1]