Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm writing a deferred renderer, and I use two FBOs: the first one for G-buffer (color, normal, depth) and the second one for lighting (light output), so the first one has three textures bound and the second one has just one.

Now, the geometry pass works just fine and all the three textures are populated correctly. After this, I try to render a full-screen quad in the lighting pass, but nothing comes to the screen - everything is black. I've even tried to use the diffuse shader program in this pass to be sure it's not a shader problem, and it's not - nothing gets drawn no matter which shader I use.

Here's some code (I've pruned out the non-relevant code)-

G-buffer initialization

// Setup buffers and textures
// FBO initialization
geometryFboId = GL.GenFramebuffer();
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, geometryFboId);

// Texture initialization
diffuseTexture = GL.GenTexture();
normalTexture = GL.GenTexture();
depthTexture = GL.GenTexture();

// Diffuse texture
GL.BindTexture(TextureTarget.Texture2D, diffuseTexture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, scrWidth, scrHeight, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);
GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, diffuseTexture, 0);

// Normal texture
GL.BindTexture(TextureTarget.Texture2D, normalTexture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, scrWidth, scrHeight, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);
GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment1Ext, TextureTarget.Texture2D, normalTexture, 0);

// Depth texture
GL.BindTexture(TextureTarget.Texture2D, depthTexture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, scrWidth, scrHeight, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);
GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment2Ext, TextureTarget.Texture2D, depthTexture, 0);

DrawBuffersEnum[] drawBuffers = new DrawBuffersEnum[] { DrawBuffersEnum.ColorAttachment0, DrawBuffersEnum.ColorAttachment1, DrawBuffersEnum.ColorAttachment2 };
GL.DrawBuffers(3, drawBuffers);

GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);

Lighting buffer initialization

lightsFboId = GL.GenFramebuffer();
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, lightsFboId);
lightsTexture = GL.GenTexture();

GL.BindTexture(TextureTarget.Texture2D, lightsTexture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, scrWidth, scrHeight, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);
GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, lightsTexture, 0);
DrawBuffersEnum[] drawBuffers = new DrawBuffersEnum[] { DrawBuffersEnum.ColorAttachment0 };
GL.DrawBuffers(1, drawBuffers);
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);


// Setup a target texture for the render
lightingTexture = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, lightingTexture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, scrWidth, scrHeight, 0, PixelFormat.Rgb, PixelType.UnsignedByte, IntPtr.Zero);
GL.BindTexture(TextureTarget.Texture2D, 0);

Render call

// Bind geometry pass
diffuseShader.Enable();
GL.UniformMatrix4(diffuseShader.GetUniformLocation("view"), false, ref Camera.main.modelview);
GL.UniformMatrix4(diffuseShader.GetUniformLocation("projection"), false, ref Camera.main.projection);
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, geometryFboId);

// Render the scene
currentScene.Render();

// Clear shaders and framebuffer
Shader.ClearShader();
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);

// Bind lighting pass
lightingShader.Enable();
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, lightsFboId);
// Misc. parameter passing here

// Render a full-screen quad
quadRenderer.Render();

// Clear shaders and framebuffer
Shader.ClearShader();
GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);

// Render output
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.ClearColor(0f, 0f, 0f, 0f);

quadRenderer.Render(gBuffer.DiffuseTexture, QuadRenderer.QuadPosition.TOP_LEFT);
quadRenderer.Render(gBuffer.DepthTexture, QuadRenderer.QuadPosition.TOP_RIGHT);
quadRenderer.Render(gBuffer.NormalTexture, QuadRenderer.QuadPosition.BOTTOM_LEFT);
quadRenderer.Render(gBuffer.LightsTexture, QuadRenderer.QuadPosition.BOTTOM_RIGHT); // Draws just black

Hopefully I didn't miss anything important here. I've checked both FBOs, and they are "complete". I've tried to pass a texture to the quad renderer, but it doesn't seem to matter. I've also tried to replace the lighting shader and lighting passes with the geometry ones, and still nothing.

share|improve this question
    
Does lightsTexture remain black if you clear it with a non-black clear color in the lighting pass? –  msell Feb 13 '13 at 6:22
    
Yeah, it does. I've tried to clear it to magenta in both shader and with GL.Clear(1f, 0f, 1f, 1f); with no resulting magenta screen. :/ –  manabreak Feb 13 '13 at 7:56
    
Have you tried gDEBugger maybe? –  Sam Hocevar Feb 13 '13 at 8:18
    
@SamHocevar No, I haven't. Maybe I should give it a try. :) –  manabreak Feb 13 '13 at 12:14
add comment

closed as too localized by Sean Middleditch, bummzack, Laurent Couvidou, Josh Petrie, Byte56 Feb 13 '13 at 18:12

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

1 Answer

I think I am missing something, here. The basic algorithm for deferred rendering is as follows:

bind geometry buffer
bind geometry shader
for each geometry
   render geometry

unbind geometry buffer
unbind geometry shader    

bind frame buffer    
bind light shader
bind textures from geometry buffer

for each light 
   bind/setup light
   render area of effect subsitute

unbind light shader
unbind frame buffer
unbind textures from geometry buffer

bind post processing effects shader
bind textures from frame buffer
render one full screen quad

Geometry part is probably in currentScene.render() but I am totally missing the iteration over all lights. And can't make anything of the last five lines.

A very good, but a but old article on the subject is Image Space Lighting over at gamedev.net

share|improve this answer
    
That's just about what I'm trying to do here. I'm using one "static" light just to test out it, but the problem doesn't lie there - even if I try only to paint everything white in the lighting pass, it doesn't do that. –  manabreak Feb 12 '13 at 15:39
    
Do you expect that quadRenderer.Render(gBuffer.LightsTexture, QuadRenderer.QuadPosition.BOTTOM_RIGHT); to render the final image? Because that makes no sense to me. –  rioki Feb 13 '13 at 9:09
    
Oh yea and where do you setup the light? Hopefully not in currentScene.Render();. Because that is the wrong place. –  rioki Feb 13 '13 at 9:10
    
What you probably want to do is render lightingTexture. But that may not even be filled with anything if there was no actual light pass. –  rioki Feb 13 '13 at 9:13
    
The light is set up in the BindForLightingPass(), it's hard-coded directional light. But that's not the case here, as I said I can't render anything, even if I try to clear the FBO with a color instead of using a shader. The whole question was about the FBO not filling up, not the lighting or the deferred rendering per se. :) –  manabreak Feb 13 '13 at 12:17
show 2 more comments

Not the answer you're looking for? Browse other questions tagged or ask your own question.