WHATA WAH? how did I not know this?

Started by
12 comments, last by TheKrust 16 years, 6 months ago
Well, I guess it's no mystery to most of you that alpha transparency doesn't work with the Z-Buffer. While this seems to be a widley known issue, I seem to have missed this somewhat horrifying fact. So, what are some methods / formulas to have your particles (smoke, fire, or even just cut-out sprites) blend in with the scene so it LOOKS like it works with the Z-buffer? So far, I have transparent sprites that are carrying the background image, but as soon as they overlap another sprite... well... you know what happens ~_~ PS. oh oh, idea here, is there a way to have the Z-buffer / object verticies tell the program what order to draw them in?
---------------------------------------- There's a steering wheel in my pants and it's drivin me nuts
Advertisement
Quote:Original post by TheKrust
Well, I guess it's no mystery to most of you that alpha transparency doesn't work with the Z-Buffer.


Actually, that's quite a mystery because alpha transparency and the Z buffer work just fine.

I think what you really mean to say is that alpha compositing is order dependent since transparency means you need to see the stuff behind the thing that is transparent. So if you draw the stuff in the wrong order, you don't end up with the stuff that is "on top" being... well, on top.

The problem isn't the Z buffer, but the order in which you draw things since Direct3D doesn't perform visibility globally like a raytracer, but locally using the Z buffer.

The standard approach is:

1. Draw all completely opaque geometry.
2. Don't draw any completely transparent geometry :-)
3. Sort partially transparent geometry by depth and draw in back to front order.

There are a few more tweaks you can do based on the transparency pattern in your geometry. If you have geometry that has opaque centers and transparent/fuzzy edges, you can use alpha test to reject the partially transparent parts and just draw the opaque parts (in any order). Then switch the test to reject opaque parts and draw the transparent parts, again sorted back to front.

To get pixel perfect accuracy, you will need to sort individual triangles back-to-front, but in reality noone does this, they just sort by the bounding box of the object.

My free book on Direct3D: "The Direct3D Graphics Pipeline"
My blog on programming, vintage computing, music, politics, etc.: Legalize Adulthood!

Quote:Original post by legalize
3. Sort partially transparent geometry by depth and draw in back to front order.


Well, that's what my PS. part was about... but how would I go about doing that? Either by standard math or some kind of pipline function.

I understand that a Z-depth test would be very easy to do as in (out of my ass example):

if (z1> z2)
draw object1
else
draw object2

but that kind of thing would become very messy once view transformations come into the equasion (maybe world transformations, but I don't honestly know).
---------------------------------------- There's a steering wheel in my pants and it's drivin me nuts
Quote:Original post by TheKrust
Quote:Original post by legalize
3. Sort partially transparent geometry by depth and draw in back to front order.


Well, that's what my PS. part was about... but how would I go about doing that?


Making a bounding box for each object.
Transform the bounding box by the current World*View matrix.
Sort the bounding boxes by their farthest away Z value.
Draw the objects in the order given by their bounding boxes.

My free book on Direct3D: "The Direct3D Graphics Pipeline"
My blog on programming, vintage computing, music, politics, etc.: Legalize Adulthood!

Quote:Original post by TheKrust
oh oh, idea here, is there a way to have the Z-buffer / object verticies tell the program what order to draw them in
If you've got your geometry stored in a space partitioning tree, such as a BSP- or Octree, it's a trivial matter to traverse it back-to-front. This article explains it rather well. Specifically, the back-to-front traversal is in the section titled "Alright, I've Got A Tree. What Do I Do With It?".
-LuctusIn the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move - Douglas Adams
Quote:Original post by TheKrust
So, what are some methods / formulas to have your particles (smoke, fire, or even just cut-out sprites) blend in with the scene so it LOOKS like it works with the Z-buffer?


There is another, easier way to do that, instead of sorting the transparent objects back to front. But this method only works in SOME cases, if the transparent objects are "completely transparent".

1. Turn off alpha blending
2. Enable Z-Buffer and Z-Buffer-Write
3. Draw all non-transparent objects

4. Turn on alpha blending
5. Enable Z-Buffer BUT DISABLE Z-Buffer-Write
6. Draw all transparent objects.


That means, transparent objects cannot occlude other transparent objects.
But transparent objects can be occluded by non-transparent objects.
If two transparent objects overlap, their colors will be mixed according to the alpha-blending settings.

I have used this method to render some kind of smoke and fire. It works well.

Hope it helps.

Mr X

[Edited by - Mr X on October 21, 2007 3:22:35 PM]
Quote:Original post by Mr X
5. Enable Z-Buffer BUT DISABLE Z-Buffer-Write


That's awesome! I wouldn't have figured that. Yeah, it doesn't cover everything, but it sure helps for now. I'm looking into some other methods as posted above, not many making sense to me... but we're all here to learn.


EDIT: after putting that into the code, accuracy wise, that is wrong on sooooo many levels, but I guess if no one can tell, who cares?
---------------------------------------- There's a steering wheel in my pants and it's drivin me nuts
Quote:Original post by legalize

Transform the bounding box by the current World*View matrix.
Sort the bounding boxes by their farthest away Z value.


so your saying I just multiply the world and view matrcies together and I should get the absolute Z value? Hmmm... past experience would suggest that's a little too easy... am I missing something or is that really it?

---------------------------------------- There's a steering wheel in my pants and it's drivin me nuts
Quote:Original post by TheKrust
Quote:Original post by Mr X
5. Enable Z-Buffer BUT DISABLE Z-Buffer-Write


That's awesome! I wouldn't have figured that. Yeah, it doesn't cover everything, but it sure helps for now. I'm looking into some other methods as posted above, not many making sense to me... but we're all here to learn.


EDIT: after putting that into the code, accuracy wise, that is wrong on sooooo many levels, but I guess if no one can tell, who cares?

That method is only accurate for additive blending, since straight addition is commutative. But other blending modes such as SRC/INVSRC give different results depending on render order.
You might want to check out Alpha Testing (as oppose to Alpha Blending) - it doesn't allow partial transparency so it won't work well for smoke etc but it works with the z-buffer and is a pretty good thing to have when rendering foilage for example.

This topic is closed to new replies.

Advertisement