Deferred Rendering: Depth-of-Field Blur
I'm writing up a DoF blur implementation, and I need your help. This involves multi-pass / deferred rendering. I would like this thread to be useful beyond what I take from it; considering there are some difficult topics involved here, this can exist as a useful, extensive source for others who would like to learn more about deferred rendering, FBOs, and obviously DoF. I would like to have a solid body of reference code here by the time we're done. I expect to learn a lot about these topics in the process.
As I understand things at present, I'm going to need to run a few passes, pushing the results into an FBO...
- Initial pass outputs the scene as ordinary, crisp quality (GL_COLOR_ATTACHMENT0), with the depth buffer (GL_DEPTH_ATTACHMENT), into the FBO.
- Second (and possibly third) pass does vertical and horizontal blur to get a maximally-blurred image (GL_COLOR_ATTACHMENT1). I've read that this would be two passes, if I use Gaussian blur. This stage is fragment shader only.
- We're now storing both the original crisp image as well as the max-blurred one, in the same FBO.
- The final pass is once again fragment shader only: We look at the depth buffer to get the blur strength. We then use gl_FragColor = mix(unblurredTex, blurredTex, blurStrength), and voila, we have composited our final image. Simplistic, but it's a start.
I would credit the approach but I cannot for the life of me find the link where I read it. The benefit here is that we maintain crispness between eg. highly blurred background objects and crisp foreground objects (that is, crispness follows the scene's z-buffer contrasts).
Here's what I have working so far:
- I've just started using FBOs. What I have at the moment is a preliminary shader pass where I render out my usual scene into an FBO for color (and later, once I've got that working, depth). So when I surround my draw calls with glDrawBuffers(...), the viewport remains blank, which I assume means everything is working: I have yet to check whether what is in GL_COLOR_ATTACHMENT0 is valid, but I've no reason to believe it's not, as my code executes OK. I use a few glDrawArrays(...) calls to do the actual rendering.
Here's what I'd like to get working next:
- Get the contents of the FBO's GL_COLOR_ATTACHMENT0 into the default framebuffer to check if it's OK (literally just a passthrough fragment shader). I've no idea how one is meant to do the second pass in client-side code, particularly as I don't think any more vertex data needs to be processed after the first pass? (so maybe glDrawArrays is no longer appropriate here...) Assistance here would be of great value as I've had little luck googling this part.
Thanks in advance for your helpful contributions. :angel:
P.S. I shall post code as soon as a little progress is made.