Skip to main content
GameDev.net gamedev.net
🔒 Locked

checking depth buffer in ps

Started by grunt123 Jul 11, 2006 at 6:23 PM 10 replies 1.9k views
Original Post
grunt123
grunt123
is it possible to check the current value of depth buffer in a given pixel in pixel shader? and the z-value of the given pixel? thanks
nts
nts
AFAIK you can not read from the depth buffer in a pixel shader. The fragment depth you should have access to, gl_FragCoord.z in GLSL, I am sure HLSL has an equivalent.

grunt123
grunt123
Is it possible to do any sort of depth test in ps then? I read from somewhere that you can do depth-test by using depth texture? Could anyone explain how this is done? Basically, i want to compare the depth value of a given pixel to the old depth value at the location of a given pixel.
Mastaba
Mastaba
Yes, sort of, but not really. The method I'm imagining would involve a multi-pass solution. Render previous frame to a depth texture (or otherwise get the depth values from the previous frame stuffed into a depth texture). Then in the next frame calculate the depth of the pixel and compare it with the value stored in the depth texture. You can then clip the pixel based on the outcome of the comparison.
m4gnus
m4gnus
Quote:
Render previous frame to a depth texture

why the previous frame? you can just render everything of this pass into as depth into a rendertarget and acces it in your shader
"There are 10 types of people in the world... those who understand binary and those who don't."
grunt123
grunt123
so, i'm assuming that using depth texture is the only way to do depth test in ps? Correct?
Thr33d
Thr33d
You probably already understood this but -

when nts mentioned the fragment depth, that means you can read the current pixel's z-value as a fragment in a pixel shader. You can also write to the z-value, atleast on my hardware. But if you start writing to z values, it generally cancels out any early z-fail test (read: slow).

I've done this before (as I'm sure many have) to create z-correct parallax mapping :) Concave intersections then have the correct intersection, it's pretty cool.

-Michael g.
Mastaba
Mastaba
Quote:
Original post by m4gnus
Quote:
Render previous frame to a depth texture

why the previous frame? you can just render everything of this pass into as depth into a rendertarget and acces it in your shader


Why previous? Because as I understand the OP question, he wants to compare the pixel's new depth with the pixel's old depth. And comparing a pixel's depth in a given frame to itself doesn't make sense.
m4gnus
m4gnus
Quote:

Why previous? Because as I understand the OP question, he wants to compare the pixel's new depth with the pixel's old depth. And comparing a pixel's depth in a given frame to itself doesn't make sense.

it does make sense rendering the current frame to a dpeth texture.
the following purposes come to my mind:

1.You could check if a fragment is visible (Edit: ok this is quite useless,except for changing the depth of the fragment depending on it's visbility)
2.Depth-dependant refraction.
3.Fog in arbitrary Meshes.

that are some that just came to my mind.
So it DOES make sense.

regards,
m4gnus

[Edited by - m4gnus on July 13, 2006 8:15:03 AM]
"There are 10 types of people in the world... those who understand binary and those who don't."
Hybrid
Hybrid
One of the best uses I've seen for reading the depth texture in a pixel shader is for soft particles (as seen in Crysis)... As the particle's Z value gets closer to the opaque geometry that was written into the Z buffer, the particle is faded out... No more intersecting particles with the world! Woohoo!
superpig
superpig
Quote:
Original post by Mastaba
Quote:
Original post by m4gnus
Quote:
Render previous frame to a depth texture

why the previous frame? you can just render everything of this pass into as depth into a rendertarget and acces it in your shader


Why previous? Because as I understand the OP question, he wants to compare the pixel's new depth with the pixel's old depth. And comparing a pixel's depth in a given frame to itself doesn't make sense.


Sure it makes sense, if you're writing to the pixel multiple times with different depths.

In general, you cannot read arbitrarily from any surface that you are currently writing to, not least because it would make things very difficult to synchronise.

As far as 'depth textures' go, be careful. NVIDIA hardware actually does support textures with depth-buffer formats, and has done since the GF3; however, it's actually a hack intended for shadow mapping, and as a result reading from those textures actually does a depth compare (using the z component of the texture coordinate) and returns 0.0 or 1.0 for use in shadowing. You can't use them to get raw depth values.

If you need actual depth values to work with, then you either need to build a separate texture to work from. If you write a vertex shader that copies the vertex depth to its texture coordinate, and then a pixel shader that outputs the texture coordinate as a colour, then you'll end up writing depths out - ideally using a floating-point texture (such as D3DFMT_R16F) for greater precision. You could build this texture either by rendering the geometry in another pass, or by using MRT and building the 'depth image' during the initial render.

However, as noted, you can't render to that depth image while you're reading from it - so when you start doing your depth-test-in-the-pixel-shader stuff, you can't update it. If you want to do the test more than once per pixel, you've got a problem. (There are solutions, but they're not pretty).
Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse
grunt123
grunt123
thx for the reply.

I just have one more question ... is it possible to copy depth buffer to a texture? i read from somewhere that you can just use some function to copy the current depth buffer to a texture ... if this is possible, then we don't really need to do MRT or do several rendering pass?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.