6
\$\begingroup\$

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!

\$\endgroup\$
1
  • \$\begingroup\$ Unfortunate that you don't have any answers yet. I would be interested in potential performance differences between the different solutions. Perhaps you can implement all 3 of them (the one you explained in detail will certainly work), compare, and post results as your own answer (reaping glorious answer rep points?). Many would thank you for it. \$\endgroup\$
    – TravisG
    Commented Oct 27, 2013 at 13:39

1 Answer 1

4
\$\begingroup\$

The second approach is the new one. they will not perform differently, it is just a flexibility of naming.

Also: yes your values will be written as-is to your textures.

now, you may want to use RGB16F targets because RGB32F are taxing on the ROPs and the bus bandwidth, which medium/small-end graphic cards do NOT have. (only the high-end cards can bind full-HD 3x 128 bits render targets at >60 FPS)

when using 16F (half floats) your values will lose precision during encoding reduction (the ROPs are operating this conversion), so careful about the range of your values (after ~32000 each step is a multi-integers jump, you don't get decimals anymore etc.)

Now, you ALSO want to reduce the number of targets to 2, by using RGBA and packing your normal as components of A of the first target and A of the second target.

Use a view-space encoding trick to store your normal in only 2 components.

This is THE resource you want to read about that: http://aras-p.info/texts/CompactNormalStorage.html

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .