Sign in to follow this  
O-san

Buffer copying

Recommended Posts

Hello! I have written a bloom shader that works on a 128x128 sized FBO. Right now I am rendering the scene twice. One time for the back buffer and one time for my 128x128 sized FBO. What I am wondering is if I can skip the last rendering pass and just copy the context from the back buffer to a 128x128 sized texture. I have thought about glCopyTexSubImage2D but it will not resize my pixel data to fit from the desktop width/height to 128x128.

Share this post


Link to post
Share on other sites
Look into the EXT_framebuffer_blit extension. The glBlitFramebufferEXT function lets you do this.

However, be aware that brutally resizing a high resolution image to such a small target will generate a lot of aliasing artifacts, since current GPUs can't do the higher order filtering needed to achieve a good quality with such extreme downsampling.

The better way is to do it like this:

* Render your main scene to a screen sized FBO1
* Render FBO1 to FBO2, which has 1/2 the original resolution
* Render FBO2 to FBO3, which has 1/4 the original resolution
* Render FBO3 to FBO4-a, which has 1/8 the original resolution
* (You can use auto-mipmap generation for the steps above)
* Finally, perform Gaussian blur on FBO4, ping-ponging between FBO4-a and FBO4-b
* Render FBO1 to the screen using a screensized quad. Apply tonemapping here, if needed, and add the contents of FBO4 (the bloom).

This method is pretty much the standard one, as used in many games and 3D samples from Nvidia and Microsoft. It is much better than a naive resize, but still exhibits serious aliasing artifacts when using HDR light sources.

If you need really high quality, do this:

* Render your main scene to a screen sized FBO1, using combined MSAA and CSAA.
* Render FBO1 to FBO2, which has 1/2 the original resolution. Use a higher order multi-tap minification shader.
* Render FBO2 to FBO3a, which has 1/4 the original resolution. Use a higher order multi-tap minification shader
* Finally, perform Gaussian blur on FBO3, ping-ponging between FBO3-a and FBO3-b
* Render FBO1 to the screen using a screensized quad. Apply tonemapping here, if needed, and add the contents of FBO3 (the bloom).

I've recently implemented the system above, because I was getting too many artifacts with standard blooming. It works very well, and is reasonably fast.

Share this post


Link to post
Share on other sites
Just a note; I'm assuming above when Yann says 'FBOx' he infact means 'texture' as swapping FBOs isn't the best way to do it.

Instead it should be faster to swap texture attachments and/or render targets instead of FBOs themselves.

Of course, if Yann has found that swapping FBOs is faster in this instance I'm sure he'll correct me [grin]

Share this post


Link to post
Share on other sites
Yeah, FBOx was probably a little misleading. I've entirely virtualized surface handling in my engine, so I tend to just think about abstract surfaces in general. I didn't really meant to specifically refer to one implementation technique or another. So, when I say FBO, you can read it as "render surface", however you actually implement this :)

About swapping textures being faster, while this is generally true, I found some hardware/driver combinations where switching FBOs is actually faster than changing the attachments. The Quadro FX 5600 notoriously shows this behaviour in stereoscopic mode. Then again, this is probably not the standard consumer level 3D card you'd target for a game [wink]

As always, YMMV, so the OP should profile his own engine.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this