Multiple render targets in GLSL... glFragData[]

Sage
Posts: 1,199
Joined: 2004.10
Post: #1
I've googled a bit, but haven't had much luck. Can anybody help me find info on how to render to multiple render targets simultaneously?

My intent is for my particle system shader to write normally to the screen, but ideally also write a du/dv map to an attached FBO. The idea being that the du/dv map would be used to do a per-pixel distortion of the rendered scene after everything's rendered. I could obviously render the particle system twice, once to the screen, and once to an FBO. But that would be expensive; the vertices would have to be processed twice, and the fragment shader for the FBO pass would have to manually sample a copy of the scene's depth buffer.

If I could make this work, it would be useful for simulation of heat ripples, or "warping" during an explosion. Could be very cool.

Basically, the Orange Book doesn't cover this, and my googling has turned up very little. I don't know how to bind an FBO as an additional render target ( alongside the normal render target, such that I can write to it via gl_FragData[N] ), and I don't know what other GL state is necessary for this to work ( or even if it does work on OS X... )

Any suggestions or pointers would be appreciated!
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #2
The basic steps are:
1) check for the extensions, limits etc. Not all renderers that support FBO support MRT.
2) create textures. They'll need to have the same format and dimensions.
3) attach textures to FBO, say at COLOR_ATTACHMENT0 and COLOR_ATTACHMENT1.
4) glDrawBuffers(2, array_of_enums)
5) now check framebuffer status-- it takes the current draw/read buffers into account.
6) write to gl_FragData[N] in your shader. N is the index into the drawbuffer array, not the color attachment index. The drawbuffer array is an indirection table. Do not write to gl_FragColor, it is mutually exclusive with gl_FragData.
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #3
arekkusu Wrote:The basic steps are:
6) write to gl_FragData[N] in your shader. N is the index into the drawbuffer array, not the color attachment index. The drawbuffer array is an indirection table. Do not write to gl_FragColor, it is mutually exclusive with gl_FragData.

That's interesting. I didn't realize that MRT doesn't mix with normal gl_FragColor writes. So I'd be render the normal color output into one FBO, and the du/dv map to another. Since I perform all my rendering directly to the screen, I'd have to grab the depth buffer and make it available to my shader.

Well, I'll mentally chew on this for a while. Seems like a bigger investment than I originally thought.

Given my rough understanding of OpenGL ES, it looks like all rendering in the future will be to an FBO; it might be wise to move my own code that way anyway, in which case this MRT stuff might be a more natural fit.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #4
TomorrowPlusX Wrote:the normal color output into one FBO,

One FBO attachment to be precise. You only need a single framebuffer object, with multiple textures attached.

You can also use MRT to write to, say, BACK and AUX0 simultaneously, if you don't want to use an FBO. But that's not very useful since you can't use AUX buffers directly as texture inputs. And all the renderers which support MRT also support FBO.

You can not simultaneously write to the window and an FBO. The drawbuffer array must contain enums for one or the other.
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #5
Thanks Arekkusu; as always, you've been able to clarify the details!
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #6
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Linking multiple glsl source files into one program TomorrowPlusX 5 6,977 Nov 2, 2006 02:18 PM
Last Post: OneSadCookie