Sign in to follow this  

WHATA WAH? how did I not know this?

This topic is 3725 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?".

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Quote:
Original post by ZipsterThat 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.

While this may be technically true, the method of using the z-buffer without z-write is still useful in a lot of particle situations. Even without additive blending (smoke, etc.) the particle system will usually look fine unless you have very few or very large particles. I think it's visually more important for the 'primary' geometry to blend correctly with the particles than for the particles to blend in proper z-order with each other.

Basically all I am saying is don't throw this technique out the window as an inferior hack, it has many valid uses!

Share this post


Link to post
Share on other sites
Quote:
Original post by TheKrust
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?


All you need to do is orient the bounding boxes so that they are in the same relative order compared to the camera as they will be when rendered. You could also multiply by the projection and viewport transformations to have them all the way in screen space, but it won't make any difference in this case, as long as you are using a reasonable projection transformation.

Share this post


Link to post
Share on other sites
Quote:
Original post by legalize
2. Don't draw any completely transparent geometry :-)


When I first read it I thought it was a point to think at....then I realized loool :D

Share this post


Link to post
Share on other sites
Quote:
Original post by fenghus
You might want to check out Alpha Testing (as oppose to Alpha Blending)


0_0... you have no idea how many problems you just solved with that one sentence...

Share this post


Link to post
Share on other sites

This topic is 3725 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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