Sign in to follow this  
Fabonymous

Depth-testing in the fragment shader

Recommended Posts

Hi,

I'm currently trying to implement a fragment shader that discards all fragments that have a great distance to the current depth value. The wished for effect: clipping decals. All fragments near to a wall get rendered. All fragments that are overlaping should get discard.

My setup is as follows:

1. Render the scene into a framebuffer object with a depth buffer attached.
2. Load the depth buffer as texture into the fragment shader.
3. Render the decals

In the fragment shader I have now two depth values, one from gl_FragCoord and one from the texture. Let calls them: fragDepth and textDepth.

[CODE]
float fragDepth = gl_FragCoord.z;
float textDepth = texture2D( depth_texture, gl_FragCoord.xy ).r;
[/CODE]

So far, so good. But the next step fails (flickering/does not what it should):

[CODE]float depthDiff = textDepth - fragDepth;
float threshold = 0.005;

if( depthDiff > threshold )
{
discard;
}[/CODE]

I'm assuming this fails due to precision issues (?)
What is the best way to proceed? Linearize the depth values? Or am I here completly on the wrong path?

Share this post


Link to post
Share on other sites
[quote name='mhagain' timestamp='1335829729' post='4936231']
Any reason not to just use standard depth testing? It will run better and give you more predictable results.
[/quote]

With standard depth testing, [i]glDepthFunc(GLenum func)[/i], you can only specify simple test like "GL_LESS", "GL_GREATER", ... as far as I understand, it is not possible to do more complicated processing in the [i]Depth Testing[/i] pipeline stage. Maybe it is possible with running multiple passes or an extension, I don't know. That's why I'm asking :-)

Share this post


Link to post
Share on other sites
I would look at example implmentations of soft particles as this is a similar test to what you want to do

Share this post


Link to post
Share on other sites
[quote name='L. Spiro' timestamp='1335950345' post='4936702']
Is there a reason why ::glPolygonOffset() will not work? It works for standard decals. Are yours not standard?


L. Spiro
[/quote]

As far as I know is glPolygonOffset() used to avoid z-fighting. Can it also be used for clipping?

Share this post


Link to post
Share on other sites
Clipping in what way? What do you want to clip? Perhaps you should explain in what way your decal system differs from the standard.
Your original post says, “clipping decals”. I don’t see what the purpose of doing that is. Z-fighting is the only issue there is to overcome with standard decals.


L. Spiro

Share this post


Link to post
Share on other sites
@L.Spiro:
I believe Fabonymous is referring to clipping decals so they dont overhang geometry - for example a splash-damage decal on the edge of a wall.

@Fabonymous:
If this is the case, I don't think depth clipping is viable either as a moving object can end up having polygons close enough to co-planar with the decal sprite, and as a result get drawn to as well. Depending on your platform, there are a few easier ways of solving it, for example performing clipping and rejection in a geometry shader and writing out to a decal vertex buffer.

Share this post


Link to post
Share on other sites
@Digitalfragment, I come to agree that depth clipping might be the wrong approach. Do you have references/sample code/tutorial on how to implement the clipping stage in a geometry shader?

Share this post


Link to post
Share on other sites
[quote name='Fabonymous' timestamp='1336046430' post='4937064']
@Digitalfragment, I come to agree that depth clipping might be the wrong approach. Do you have references/sample code/tutorial on how to implement the clipping stage in a geometry shader?
[/quote]

DICE has a [url="http://publications.dice.se/attachments/GDC09_ShadowAndDecals_Frostbite.ppt"]presentation[/url]. It's complicated. You may not want to give up on projected decals so easily...games have shipped with it. [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

Share this post


Link to post
Share on other sites
@[url="http://www.gamedev.net/user/198131-fabonymous/"]Fabonymous[/url]

Late to the party but in case you or someone else happens to this:

[quote]
float textDepth = texture2D( depth_texture, gl_FragCoord.xy ).r;
[/quote]

This is not going to give you the depth value you expect. gl_FragCoord gives you screen coordinates (screenWidth, screenHeight), so depending on your screen resolution the values change dramatically. For instance at 800x600 gl_FragCoord will give you something in the range of (0-800, 0-600).

You want your texture coordinates to be between 0-1 when sampling the depth texture. So what you need to do is convert gl_FragCoord (screen coords) to something usable. To do that, you simply divide by the screenWidth and screenHeight.

[CODE]
// Samples wrong location in the texture
//float textDepth = texture2D( depth_texture, gl_FragCoord.xy ).r;
// First translate the screen coordinates to texture coordinates
vec2 texCoords = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);
// Now sample the depth
float textDepth = texture2D( depth_texture, texCoords);
[/CODE]

If you know the screenWidth and screenHeight are always the same, you can just hard code in the values. Otherwise, you can pass them to your shader using Uniforms

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