PDA

View Full Version : Getting depth info from alpha-blended scenes



gsmith
12-15-2003, 12:24 AM
I'm rendering a scene that has a number of layers. Like I've got say six RGBA textured quads all overlapping, these are rendered back to front and alpha blended so that you can see through the transparent parts of each layer. This view works well when the camera moves around the scene.

Now I need to find some way of telling which layer I'm looking at at pixel/fragment level (this is for a special effect I'm ptotyping). As I see it though, I can't get this from the depth buffer (which is disabled anyway for blending) as this doesn't take into account the transparent areas. Is there some way I can use - fragment program, render to texture etc. - that can give me the "depth" info for an individual fragment? By "depth", I mean the first non-transparent layer that's showing?

I've busted my brain trying to think of a way round this and I've more or less reached the conclusion that it can't be done, except maybe in a static scene. I'm using GF4 if that makes any difference.

Does anyone here have any bright ideas?

Thanks,
George

Christian Schüler
12-15-2003, 02:45 AM
Why?
If you say that depth-writes are disables for transparent geometry, then the contents of the depth buffer is the first non-transparent surface visible.

gsmith
12-15-2003, 03:48 AM
But my surfaces are only partially transparent. For example, there is a border area which is textured with alpha==1, and a transparent "window" in the centre with alpha==0. So when two such surfaces are blended from back to front, the border of the frontmost surface obscures the surface behind it, while the backmost surface shows through the alpha==0 window.

Are you saying that, in the above situation, I can enable depth buffer writes and then the depth buffer will hold the depth of the frontmost surface in the border area and the depth of the rearmost surface in the transparent "window"? Note that this should be true no matter how many similar intervening surfaces exist. This is not what I've found by experiment (but I may have made an error) http://www.opengl.org/discussion_boards/ubb/wink.gif

G.

ZbuffeR
12-15-2003, 04:08 AM
Originally posted by gsmith:
Are you saying that, in the above situation, I can enable depth buffer writes and then the depth buffer will hold the depth of the frontmost surface in the border area and the depth of the rearmost surface in the transparent "window"?
It will only work this way with alpha testing, not alpha blending. If you have only pure 0.0 or 1.0 alpha values, alpha testing is the way to go, but you will get sharp 'edges' instead of blurry transitions from alpha 1 to alpha 0.

You may want to use your current method (alpha blend + no tranparent depth write), and on second pass only write to zbuffer with alpha testing.

EDIT: If you have in-between alpha values (0.3 etc) , google for 'depth peeling', I think nvidia has a gl demo in its sdk. But it seems much more complicated.

[This message has been edited by ZbuffeR (edited 12-15-2003).]

gsmith
12-15-2003, 04:19 AM
Originally posted by ZbuffeR:
You may want to use your current method (alpha blend + no tranparent depth write), and on second pass only write to zbuffer with alpha testing.

Will that work ok for 0.0 < alpha < 1.0 as well? Does the alpha test look only at the incoming fragment and not what is already in the frame buffer?

I'll check out the "depth peeling" link too - thanks for the clue http://www.opengl.org/discussion_boards/ubb/smile.gif

George

zeckensack
12-15-2003, 04:21 AM
Render to depth texture ... I think a search for "shadow map" might turn up useful results. That covers depth (per layer).
You may be ablte to fix your alpha issue by using EXT_blend_min_max (or whatever it's called), and copying the resulting alpha channel to another texture.

Then you can feed these results into a fragment program and do what you want, but it will require a lot of passes.

ZbuffeR
12-15-2003, 06:41 AM
Originally posted by gsmith:
Does the alpha test look only at the incoming fragment ?
Yes, read the spec of glAlphaFunc.
glAlphaFunc(GL_GREATER,0.1)
to write only fragments above 0.1 alpha. Enable depth write, and there is no need to do a second pass, contrary to what I said. sorry http://www.opengl.org/discussion_boards/ubb/smile.gif

If you need more than one depth value per pixel, you have to do it the hard way like said above.