Z-Fighting issue when attempting to early-z

Started by
6 comments, last by stramit 16 years, 8 months ago
Hi guys and girls, I've been playing around with my graphics engine trying to do some early-z in conjunction with my shadow volumes, but I am having an odd issue, the second time I render the scene (with z writes turned off) the depth test seems to be playing up. (This is with a 24bit depth buffer) Here is a picture of what I am seeing happening: z-fighting The code I am using to render this scene is as follows:

    //Initialise the renderpass
    GL11.glClear( GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_COLOR_BUFFER_BIT );
    GL11.glMatrixMode( GL11.GL_MODELVIEW );
    GL11.glLoadIdentity();
    activeCamera.lookAt();

    //Perfrom the early z pass
    GL11.glEnable( GL11.GL_DEPTH_TEST );
    GL11.glDepthFunc( GL11.GL_LEQUAL );
    GL11.glDepthMask( true );
    GL11.glColorMask( false, false, false, false );
    drawScene();

    //Do the colour pass
    GL11.glDepthFunc( GL11.GL_LEQUAL );
    GL11.glDepthMask( false );
    GL11.glColorMask( true, true, true, true );
    light.bind();
    drawScene();
    light.unBind();


I am probably missing something simple, but in all my searches I have been quite unable to find much information on how to properly perform an early z pass. Any help would be much appreciated, as I am sure some of you have seen this issue before. Thanks again.
Advertisement
Code would be much more useful if you would say (roughtly) what drawScene does. Does it uses shaders for first?
Quote:Original post by stramit
I am probably missing something simple, but in all my searches I have been quite unable to find much information on how to properly perform an early z pass.
You don't find it because it takes a bit of secret sauce. A sort-of-ok Zpass just takes redrawing everything as you're doing. More complex methods would include consider the texture type, fragment discard issues and the blend type togheter with a bit of shader remangling...
Quote:Original post by stramit
Any help would be much appreciated, as I am sure some of you have seen this issue before.
Yes, I've seen a similar issue which was related on viewport near/far ratios. The near plane caused too much precision to be lost, which showed a similar pattern under some cases.
However, I don't see how this could affect you. If the two drawscene calls are the same under the same input vector they should give the same results so the artifact should be present even when not multipassing - a thing that I guess doesn't happen.

Previously "Krohm"

If you mix shaders and fixed function pipeline, that the artifacts are most likely caused by the vertex shader

there is a function ftransform()

gl_Position = ftransform();

which guarantees that the result stored in gl_Position matches the result, if you were using fixed function.


The shader internal floating point operations may differ from fixed function due to rounding errors.



also make sure you are using less equal as compare function everywhere.



http://www.8ung.at/basiror/theironcross.html
z only pass is nothing special, basically what u hhave there

the problem is that diferent depth values are somehow created
perhaps one pass is using
glVertx = glftransform();
and the other
glVertx = glModelviewprojection * vertex;

or one pass has clipplanes enabled and the other doesnt
Thank you for the help guys, but I have tried most of what you have mentioned already. Originally I was using the FFP for the depth write and a shader with ftransform() for the vertex location when I was performing the shading.

I have stripped my render pass back to the very basics to try and figure this out, and the draw scene has been replaced with a simple quad.

    //Initialise the renderpass    GL11.glClear( GL11.GL_COLOR_BUFFER_BIT );    GL11.glClear( GL11.GL_DEPTH_BUFFER_BIT );    GL11.glClear( GL11.GL_STENCIL_BUFFER_BIT );    GL11.glMatrixMode( GL11.GL_MODELVIEW );    GL11.glLoadIdentity();    //Uses GLULookAt internally    activeCamera.lookAt();    //Perfrom the early z pass    GL11.glEnable( GL11.GL_DEPTH_TEST );    GL11.glDepthFunc( GL11.GL_LEQUAL );    GL11.glDepthMask( true );    GL11.glColorMask( false, false, false, false );    //Fill the depth buffer with each object    simpleShader.bind();    GL11.glBegin( GL11.GL_QUADS );    GL11.glVertex3f( 20, -4, -20 );    GL11.glVertex3f( -20, -4, -20 );    GL11.glVertex3f( -20, -4, 20 );    GL11.glVertex3f( 20, -4, 20 );    GL11.glEnd();    simpleShader.unbind();    //Do the colour pass    GL11.glEnable( GL11.GL_DEPTH_TEST );    GL11.glDepthFunc( GL11.GL_LEQUAL );    GL11.glDepthMask( false );    GL11.glColorMask( true, true, true, true );    simpleShader.bind();    GL11.glBegin( GL11.GL_QUADS );    GL11.glVertex3f( 20, -4, -20 );    GL11.glVertex3f( -20, -4, -20 );    GL11.glVertex3f( -20, -4, 20 );    GL11.glVertex3f( 20, -4, 20 );    GL11.glEnd();    simpleShader.unbind();


simpleShader
vert:void main(){  gl_Position = ftransform();}frag:void main(void){  gl_FragColor = vec4(0.5, 0.5, 0.5, 1.0);}


And an image of what it renders:


It's almost like the depth buffer is being corrupted, especially as I am drawing exactly the same quad twice :S

Here is what my initialisation looks like for the near / far planes and GL in general:
      //Create display      GL11.glViewport( 0, 0, activeMode.getWidth(), activeMode.getHeight() );      GL11.glMatrixMode( GL11.GL_PROJECTION );      GL11.glLoadIdentity();      //I have tried multiple near / far values.... 1 / 10; 5 / 50 ect       GLU.gluPerspective( 45.0f, (float) activeMode.getWidth() / (float) activeMode.getHeight(), 0.2f, 100.0f );      GL11.glMatrixMode( GL11.GL_MODELVIEW );      GL11.glLoadIdentity();      //Set up render properties      GL11.glShadeModel( GL11.GL_SMOOTH );      GL11.glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );      GL11.glClearDepth( 1.0f );      GL11.glEnable( GL11.GL_DEPTH_TEST );      GL11.glDepthFunc( GL11.GL_LEQUAL );      GL11.glHint( GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST );      GL11.glEnable( GL11.GL_CULL_FACE );      GL11.glCullFace( GL11.GL_BACK );


Any ideas?
What if you don't unbind the simpleShader between the passes?

Previously "Krohm"

Same thing, I should have noted that in my post.

This issue is driving me a bit crazy :S

edit: Just ran it on my windows PC with the same result :S
Thank you everyone for your suggestions, I have tracked down the issue....

At the end of the renderpass I was not setting the depthmask back to true, because of this when I cleared the depth buffer, it was not actually being cleared as the mask was off. This meant that each frame was using the same depth buffer :S

Anyways, here is a picture of my renderer in it's current state (including simple early-z), it's coming along quite well, parallax, HDR, tonemapping, bloom, volume shadows.



Thanks everyone for your time.

This topic is closed to new replies.

Advertisement