Multi-pass lighting problem (Solved).

Started by
2 comments, last by Aikavanak 15 years, 9 months ago
Hey! I've just implemented shaders in GLSL for per-pixel lighting, and am trying to get a multi-pass system working for rendering multiple dynamic lights. From what I've read in books and on these forums, the basic idea is to render ambient light in an initial pass, and then add the diffuse lighting components in the next passes. It also seems like a good idea to write the z-buffer in only the first pass, to save time in the later ones. However, this doesn't seem to be working in my code. (The gl. prefix on all my calls is because I'm using Java and JOGL). In my initialization code, I do this:

gl.glEnable(GL.GL_BLEND);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glDepthFunc(GL.GL_LEQUAL);



My rendering code looks like this:

gl.glClear(GL.GL_COLOR_BUFFER_BIT|GL.GL_DEPTH_BUFFER_BIT);
		
// Ambient and depth buffer pass.
gl.glBlendFunc(GL.GL_ONE,GL.GL_ZERO);
// Enable depth buffer writes.
gl.glDepthMask(true);
		
ambientShader.enable();
		
renderScene();
		
ambientShader.disable();
		
// Lighting passes.
// Add new fragment colors to colors from previous pass.
gl.glBlendFunc(GL.GL_ONE,GL.GL_ONE);
// Disable depth buffer writes.
gl.glDepthMask(false);
		
diffuseShader.enable();
		
for(int i=0;i<lightManager.getNumLights();i++)
{
    diffuseShader.sendUniform("lightIndex", i);
			
    renderScene();
}

diffuseShader.disable();



The result of the above code is what appears to be intense z-fighting. If I set DepthMask to true for the diffuse passes, it looks fine. I have also tried changing the depth function for the diffuse passes to GL_EQUAL, but it doesn't change anything. I would really like to take advantage of the speed of writing the depth buffer only once. Can anyone see a problem with my code? Or offer other things to try? Thanks! [Edited by - Aikavanak on July 10, 2008 11:36:57 PM]
Advertisement
"Rendering the depth buffer once initially, setting depth function to GL_EQUAL with depth mask disable for the blending passes" is perfectly okay.

The z-fighting issue you experiencing is probably came from inconsistent setting between the initial pass and the blending passes which can cause a different in z-value due to numerical error.

For example, the projection matrices are not identical.

Or, for another example, the initial pass is rendered using the fix-pipeline functions directly while the blending passes are rendered using your own shader.
Thanks for the reply.

I double-checked my code, and everything between the passes should be the same, except what I posted above, namely, the blending function, depth mask, and shader. Both of my shader programs have an attached vertex and fragment shaders, so the fixed-function pipeline should not be involved.

I really don't think the problem is in the shaders, because I can get correct-looking results if I enable depth mask for the other passes. If anyone wants to see the shaders anyway, I can post that code too.


UPDATE: I don't think the artifacts I'm seeing are a result of z-fighting, as I'd never seen z-fighting before. What's happening is that sections of my rendered geometry is disappearing - I can see the background color where there should be textured, lit polygons.

[Edited by - Aikavanak on July 5, 2008 11:52:28 PM]
Someone in another forum noticed my mistake (thanks ihkbob!), so I'll post it here for anyone interested.

I wasn't calling glDepthMask(true) before glClear()! So even though I was passing GL_DEPTH_MASK to glClear, it wasn't actually writing to the depth buffer. Adding the extra call to glDepthMask solved the problem.

This topic is closed to new replies.

Advertisement