What is the recommended way to output values to FBO targets? (OpenGL 3.3 + GLSL 330)

Posted by datSilencer on Game Development See other posts from Game Development or by datSilencer
Published on 2013-02-19T19:30:53Z Indexed on 2013/10/26 4:12 UTC
Read the original article Hit count: 229

Filed under:
|

I'll begin by apologizing for any dumb assumptions you might find in the code below since I'm still pretty much green when it comes to OpenGL programming.

I'm currently trying to implement deferred shading by using FBO's and their associated targets (textures in my case).

I have a simple (I think :P) geometry+fragment shader program and I'd like to write its Fragment Shader stage output to three different render targets (previously bound by a call to glDrawBuffers()), like so:

#version 330

in vec3 WorldPos0;
in vec2 TexCoord0;
in vec3 Normal0;
in vec3 Tangent0;

layout(location = 0) out vec3 WorldPos;
layout(location = 1) out vec3 Diffuse;
layout(location = 2) out vec3 Normal;

uniform sampler2D gColorMap;
uniform sampler2D gNormalMap;

vec3 CalcBumpedNormal() {

    vec3 Normal = normalize(Normal0);
    vec3 Tangent = normalize(Tangent0);

    Tangent = normalize(Tangent - dot(Tangent, Normal) * Normal);
    vec3 Bitangent = cross(Tangent, Normal);
    vec3 BumpMapNormal = texture(gNormalMap, TexCoord0).xyz;

    BumpMapNormal = 2 * BumpMapNormal - vec3(1.0, 1.0, -1.0);

    vec3 NewNormal;
    mat3 TBN = mat3(Tangent, Bitangent, Normal);
    NewNormal = TBN * BumpMapNormal;
    NewNormal = normalize(NewNormal);

    return NewNormal;
}

void main() {
    WorldPos = WorldPos0;
    Diffuse = texture(gColorMap, TexCoord0).xyz;
    Normal = CalcBumpedNormal();
}

If my render target textures are configured as:

RT1:(GL_RGB32F, GL_RGB, GL_FLOAT, GL_TEXTURE0, GL_COLOR_ATTACHMENT0)
RT2:(GL_RGB32F, GL_RGB, GL_FLOAT, GL_TEXTURE1, GL_COLOR_ATTACHMENT1)
RT3:(GL_RGB32F, GL_RGB, GL_FLOAT, GL_TEXTURE2, GL_COLOR_ATTACHMENT2)

And assuming that each texture has an internal format capable of contaning the incoming data, will the fragment shader write the corresponding values to the expected texture targets?

On a related note, do the textures need to be bound to the OpenGL context when they are Multiple Render Targets?

From some Googling, I think there are two other ways to output to MRTs:

1: Output each component to gl_FragData[n]. Some forum posts say this method is deprecated. However, looking at the latest OpenGL 3.3 and 4.0 specifications at opengl.org, the core profiles still mention this approach.

2: Use a typed output array variable for the expected type. In this case, I think it would be something like this:

out vec3 [3] output;

void main() {
    output[0] = WorldPos0;
    output[1] = texture(gColorMap, TexCoord0).xyz;
    output[2] = CalcBumpedNormal();
}

So which is then the recommended approach? Is there a recommended approach at all if I plan to code on top of OpenGL 3.3?

Thanks for your time and help!

© Game Development or respective owner

Related posts about opengl

Related posts about glsl