Sign in to follow this  
stramit

Z-Fighting issue when attempting to early-z

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.



Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

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