Sign in to follow this  

Depth peeling and z-clipping

This topic is 1114 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

 

I have a shader where I create several frame buffers and perform N passes through my display list. In the first pass I simply store the image and depth; in the second and all subsequent passes in the fragment shader I compare the current depth with the previously saved one and discard if it's in front of it. Then I blend all images in a final post-processing phase at swap time.

 

This all works fine, except for when there's z-clipping going on. I saved both the color and depth textures associated with each frame buffer and save all of them to a bmp file so I can see what's going on. I have just a few intersecting cones being displayed. In the area where z-clipping occurs both the depth and the color textures seem to have garbage defined on them.

 

I'm wondering whether there's something I'm not aware of regarding the data coming in. For example, I assume that gl_FragCoord.z is always between 0 and 1, and anything that's being clipped won't even go through the fragment shader. Is this the case? Or is z-clipping done after the fragment shader? In this case, should I expect gl_FragCoord.z < 0 or > 1 to be allowed?

 

I'm attaching the saved color texture. The solid colors are what I expect to see. The fuzzy area is exactly where the z-clipping plane is passing through. Any thoughts?

 

Thanks.

Share this post


Link to post
Share on other sites

After some more reading I suspect my problem has to do with the fact that I created a 2D texture to store the depth and then I'm comparing the depth value from a previous pass (stored in the texture) with gl_FragCoord.z. But in order to retrieve the previous value I need to pass to texture2D the texture coordinates between 0 and 1, and this rounding-off depending on screen size may just be returning to me the incorrect pixel. And with depth values probably extremely close to each other the comparison is failing, thus giving me the bad image I'm seeing.

 

This is all speculation, but if I'm right now I have more concrete questions that I'm hoping somebody can help me with:

 

1) Is there a way to query a sampler2D in the fragment shader given the center pixel location values - gl_FragCoord.xy? Of course, these will not go from 0 to 1, but from 0 to width and 0 to height. Given that gl_FragCoord will have values such as (1.5,3.5), I can easily pick the exact pixel. But if I need to map gl_FragCoord to texture coordinates between 0 and 1 I'm bound to run into this round-off issue.

 

2) My depth peeling algorithm requires multiple passes through my display list. This means that, at the same time, I need to both retrieve the depth and save it on another texture on pass, AND I need to accurately compare the depth to gl_FragCoord.z. I am using only sampler2D. Maybe I should be using sampler2DShadow instead to store my depth value. But from what I understand, querying the sampler2D using texture coordinates I get the floating point depth back; and querying a sampler2DShadow with a vec3 value returns only 0 or 1, depending on the result of the comparison.

 

What exactly should I be using in my fragment shader so I can both compare and store the depth value accurately?

 

3) Depending on the answer to the question above, what parameters should I be setting in the depth texture on the client side?

 

Thanks.

Share this post


Link to post
Share on other sites

Yet another update: I changed the texture type to GL_TEXTURE_RECTANGLE. This way I can directly use gl_FragCoord.xy when passing data to the textures. I'm using the defaults, so I assume gl_FragCoord.xy will have values like 0.5, 1.5, 2.5, etc.

 

I store all my display data on display lists. I draw my display list once and save the color and depth buffer by create a frame buffer with GL_TEXTURE_RECTANGLE textures for both - one color, and one depth. The filters on both textures are set to GL_NEAREST.

 

I query the depth texture using

 

float depth = texture (depthtex,gl_FragCoord.xy).r;

 

My expectation is that this call should always find the exact same texel in my texture; so it writes the color and depth on one pass and reads with the exact same coordinates on the next path.

 

But, unfortunately, this is not the case. I "solved" my problem by using a tolerance such as

 

if(depth >= gl_FragCoord.z - 0.00001) discard;

 

on the second time I draw. The image looks perfect - pointing to the fact that this was indeed my problem. But

 

1) Why do I not get the exact same values on the second pass as the first pass, or... why does my comparison fails at times?\

 

2) Can I get better results by using different texture parameters?

 

Thanks.

Share this post


Link to post
Share on other sites

This topic is 1114 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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