Sign in to follow this  
Ravuya

FBO MRT questions (Was: FBO/MRT corruption on nvidia)

Recommended Posts

Ravuya    135
On my ATI card at home, I have an FBO with two colour attachments and a depth buffer, and I am writing to gl_FragData[0] and gl_FragData[1] in the fragment shader. I am using glDrawBuffers(2, attachments) with attachments = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }. The colour attachments are texture rectangles. It works fine on my ATI X1600 on my Macbook Pro. For some reason, when I am rendering on NVidia cards (on Linux or OS X), the draw into gl_FragData[1] seems to get garbage fragments written into it. I had seen this problem before, but it was because I was writing into one or the other gl_FragData locations and uninitialized garbage was going into the unused one. What is the proper procedure for rendering to an FBO with more than one colour buffer in a shader? On the application side, I am just using glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) after binding the FBO; am I missing a technique for clearing out FBOs properly even though I should be overwriting those texels in the shader? In the below screenshot, the "F" buffers (FDepth and FNorms) are one FBO, rendering the front faces of the object, with two colour attachments (FNorms = gl_FragData[0], FDepth = gl_FragData[1]). The "B" buffers are another FBO, rendering the backfaces of the object, with the same setup. I know the geometry is solid because the first colour buffer seems to work fine. Any help would be appreciated. [Edited by - Ravuya on April 29, 2009 12:20:52 PM]

Share this post


Link to post
Share on other sites
deadstar    536
Quote:
Original post by Ravuya
I am just using glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) after binding the FBO; am I missing a technique for clearing out FBOs properly even though I should be overwriting those texels in the shader?


This caused a similar issue for me, eventually I cleared all MRTs using a shader. I don't think the fixed function method takes all MRTs into account. It's in Cg, but I'm sure you get the idea:


float4x4 WorldViewProj : WorldViewProjection;

struct VInput
{
float4 Position : POSITION0;
float2 UVCoord : TEXCOORD0;
};

struct VOutput
{
float4 Position : POSITION0;
float2 UVCoord : TEXCOORD0;
};

struct POutput
{
float4 Albedo : COL0;
float4 Normal : COL1;
float4 Depth : COL2;
};

VOutput VShader(VInput Input)
{
VOutput Output;

Output.Position = mul(WorldViewProj, Input.Position);

return Output;
}

POutput PShader(VOutput Input)
{
POutput Output;

Output.Albedo = 0.0f;
Output.Normal.rgb = 0.5f;
Output.Normal.a = 0.0f;
Output.Depth = 1.0f;

return Output;
}

technique Main
{
pass p0
{
CullFaceEnable = false;
VertexProgram = compile vp40 VShader();
FragmentProgram = compile fp40 PShader();
}
}



Hope it helps.

Share this post


Link to post
Share on other sites
Ravuya    135
Followup: Looks like it is the shader's fault and not the FBO. The position I was passing in was uninitialized:

fragmentPosition = gl_ModelViewMatrix * gl_Position;
gl_Position = ftransform();





So this thread actually serves a reference purpose in future, what is the 'correct' way to do MRT with FBOs? I have a ton of problems with my FBO class because I've had to bodge in stuff like texture rectangles to support various kinds of hardware.

Basically what I do is the following:
- Initialize the FBO
- Create and bind depth buffer
- Create and bind colour buffer(s)
- Check FBO completeness

- When it comes time to bind, I bind the FBO
- I do glDrawBuffers(colourBuffers.size(), colourBuffers)
- I do whatever, the shader points to gl_FragData[n] to route output to a particular colour buffer
- I unbind the FBO object and use the colour buffers' backing handles with impunity.

Sorry to have wasted anyone's time who took the time to reply. I gave deadstar a ratings bump for his help; I will definitely move to an FBO-clearing shader because I still don't trust the fixed function fully.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this