Multiple FrameBuffers and MRT

In my last article I wrote about the Render To Texture (RTT) technique used in many games for advanced rendering. Now we can talk about Multiple FrameBuffers Objects and MRT (Multiple Render Targets) to create even more complex scenes using RTT.

Portal 2

Multiple FrameBuffers Objects

Let’s start with an example where we have a complex scene to render. Imagine that you have a game with portals and each portal renders a different scene; there is some movement in those scenes, like robots or birds (dynamic movement) and you have to choose in which portal you should jump into, based on how dangerous is that world. Also the size of these portals are different. Now, you can render those portal scenes into different textures or renderbuffers and composite them into the final scene where we finally render everything. We can achieve this by using multiple framebuffers (FBOs). I created a simple example (without portals of course) where I have 2 framebuffers. To create them I used the same class that we generate a FBO from my last article . Also for rendering we need 3 shaders: one (or more) to render the scene, one to render the depth and one to render with blur:

In the first pass we render the scene into first FBO and we get the color texture and the depth texture.

In the second pass we will use the second FBO and render the depth buffer texture from the first pass with the second shader.

Finally we take the depth texture from second pass and we apply some blur to it in pass 3.

It’s not the best example in the world but it should give you a good idea on how to use more framebuffers. Also this example could be done by using the same shader for depth and blur (pass 2 and pass3) and just send a control variable as an uniform to decide what you want. For both textures we have the same width and height. Tips: Don’t render depth texture last, because in pass 2 we render a quad in NDC and you end up with a black image (0.0 is close and 1.0 is far).

One super important feature of a framebuffer is the ability to render to multiple buffers simultaneously which gives us a lot of power. With this power you can render your scene in a bunch of textures with different storage formats. You can use all these textures in another pass to create multiple post-processing effects or deferred lighting. Also you can create multi-pass rendering with just a single framebuffer by drawing scenes in different textures or renderbuffers using OpenGL’s function glDrawBuffers to tell in which attachment it should draw.

Now let’s see how MRT actually works. To access multiple buffers we first have to get the output from our main scene fragment shader. Maybe we want to see how world position looks like and we want to render it in a texture. To do this we output world position to a new layout location.

Multiple Render Target

As you can see from the picture above, we also need to change the GenerateFBO method ( from Part I). What we have to do is to create another texture to store the world positions in order to render it in Pass 2

In conclusion, use MRT when you need to get more buffers from your scene and use multiple FBOs when you have a bunch of additional scenes (eg. mirrors or portals) that are rendered into main scene. It’s usually a good practice to keep your code clean in this complex scenario and use one FBO for one additional scene. In this way you can create and use different textures sizes and formats.

My code is structured from one of my projects and it should be used only for learning purpose.

I have been working as a software engineer in computer graphics for almost 5 years. In the free time I love playing guitar, playing video games, hiking and studying computer graphics techniques.Follow me on : Google + , Twitter, Facebook