Depth testing without the depth buffer

Started by
8 comments, last by Hodgman 11 years, 6 months ago
So I had this beautiful renderer that I wrote and then I decided to implement a particle system. The particles themselves work great but they conflict with my ssao shader because they write to the depth buffer during depth testing and end up causing an ugly shadow when ssao is reading from the depth buffer. I can solve this by disabling writing to the depth buffer but then my particles are not tested. Is there a way to depth test my particles without them being written into the depth buffer?
Advertisement
Disabling depth writes does not disable the depth test. Are you sure you actually disabled the depth writes, and not depth testing?

Disabling depth writes does not disable the depth test. Are you sure you actually disabled the depth writes, and not depth testing?


I used glDepthMask(0). The particles are getting tested against whats already drawn but since other particles haven't been written to the buffer that means that they aren't getting tested against each other.
this is one of the unfortunate problems we all have, with i think any rasterizer
its too bad, that we "arent there yet", when it comes to 3d graphics smile.png
and for at least a decade more the graphics will be rendered in the same exact way..
for most problems you can hack together a solution, like the plethora of anti-aliasing solutions, GI, SSAO.. all hacks smile.png

in my experience, i have no solution to your problem except to zsort particles and anything else that uses alpha
the alternative as stated above is to turn off depth writes, however..

what's even harder is fading out the world, because you really don't want to do that in the frag program of each vertex!
so, i had the not so good idea to fade the world in the screenspace shader, which relies on depth testing again!
well, as you can imagine that also creates some interesting problems:
being above clouds ruins depth (can't turn off depth write or the clouds will ignore mountains sticking up over them
being underwater ruins depth (it's not like i can turn off depth write here)
any particles etc. also ruins depth (but you can cheat and turn it off)
so what am i to do? i don't know smile.png but if anyone knows, PLEASE do tell! smile.png

edit: oh, i forgot to mention that any object that doesnt depth-write would be faded out with the depth of the object behind it smile.png
such a small problem, but no solutions!
i have tried running the screenspace world-fader before any objects.. but then i would lose any depth-information on the screen
So, you want the particles to be depth-tested and written to the depth buffer during the particle pass, but have the SSAO pass run as if they weren't written? Something like this springs to mind:

Create a second depth buffer. Before the particle pass copy the first to it, then set it as active. Then run particles with depth testing and writing both enabled. Then switch back to using the first for the SSAO pass.

I have to admit that I have no idea whatsoever how well (or not so well) this would run. Copying the first depth buffer to the second gives me the horrors, but the alternative is to write out a second copy of depth during the regular rendering passes, which may well be worse.

It may alternatively be possible to do something with the stencil buffer, but that might not work so well if you're already using it for something else.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Can you just do your SSAO calculation before rendering the particles?

Can you just do your SSAO calculation before rendering the particles?


problem is then the depth information from the original scene is lost after having gone through a "musical chairs" of fbo's so the particles cant be depth tested against the original scene.
One idea would be to store the particles in a octree, which can be used for sorting them. There is of course the risk that this may add too much cost.
[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/
Another idea is to cheat a little about the sorting, it depends a little on how frequently the particles cover each other, and how much alpha you use. The idea would be to update a manual depth buffer (in addition to the old one) with the information about the nearest pixel. You also need a separate blend buffer. Every time a particle is drawn, the manual depth buffer is updated. But it is not used for culling, so all particles will still be drawn. The trick then is how to do the blending. When a pixel is updated, the new pixel would be either SRC + DEST, or DEST+ SRC, depending on whether it was in front or behind the current depth. To find out if is it in front or behind, a test of the depth against the manual depth is done. Premultiplied alpha should be used, which allows for associative blend operations.

This would guarantee the sort being correct with up to two writes to a pixel. With more writes, the foremost will always be correct.

What i don't know, and it may invalidate the proposal, is how to efficiently manage the "read-modify-write" that is needed for buffers.
[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/
problem is then the depth information from the original scene is lost after having gone through a "musical chairs" of fbo's so the particles cant be depth tested against the original scene.
Can you fix this so that you don't lose depth along the way? e.g. use the same depth target with each FBO binding?

This topic is closed to new replies.

Advertisement