Jump to content
  • Advertisement


This topic is now archived and is closed to further replies.


Transparency been buggin' me

This topic is 5654 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

Hello! Here's a little question about transparency in DX9. I'm imagining it won't take long to answer - I'm sure I've just missed something important in the theory. Imagine you have a particle system that shoots out particles, which are billboarded square-shaped primitives, in random directions. As the particles get closer to their death, they fade - there is a direct correlation between the life they have left and the particle's material's alpha component:
Particle.Material.a = Particle.LifeLeft;
So you get a bunch of fading particles, becoming more and more translucent as time passes. When you look at some particles floating around in front of the others, you can see the 'back' particle through the front one, which is the desired effect. However, some particles cannot be seen through some other particles. I know this is all down to the render order, and the way that the first particles to be rendered just blend their alpha components with the back buffer. Any particles rendered after that, behind the first particles, cannot be seen through them. This is to do with my simple rendering loop:
for( UINT i=0; i<MAX_NUM_PARTICLES; i++ )
I know one solution would be to create a sorted list of all the particles in the system and render them from the back of the scene to the front. My question is is there a simpler way to, say, look at the scene, including all of its objects and their transparency properties, as a whole, so that translucent objects will always reveal the objects behind them, regardless of the render-order of the objects in the scene? Maybe there's some way of rendering a scene twice, once with all the objects in place, then again with the transparency and translucency, using the first rendering as the source? I'd like to hear if there are any standard ways of doing this that I have missed, or if anyone has created a handy work-around. Thanks! [edited by - GazzyG on June 19, 2003 1:35:10 PM]

Share this post

Link to post
Share on other sites

The only way I know to completely skip sorting is to use additive blending. Since everything is just summed, the order doesn''t matter.

You would have to redo your particle art and handling to look right with that method, but it''d work.

Stay Casual,

Drunken Hyena

Share this post

Link to post
Share on other sites
read this

or search the word "D3DRS_ALPHAFUNC" on GameDev Forum... there are some interesting post...

Share this post

Link to post
Share on other sites
Thanks for your suggestions, they''re all appreciated!

The one method I have found of rendering all particles in my system without artifacts appearing from particles being rendered in front of others is to use the renderstate:


This makes the z-test for rendering always return TRUE, so every translucent/transparent pixel can exposes whatever pixels are behind it.

This is fine for a simple demo of a particle system. Unfortunately, it''s no good if you want to render a whole scene. So I decided to try sorting the particles, using the ''qsort'' function like they used in the DirectX 9 Billboard sample program.

I altered the code of the callback function that qsort uses for comparing values so that it now compares the distances of the two particles from the camera, not simply their z-values (that would only be of any use for a fixed-position camera, as far as I can make out). However, even with this distance-from-camera sorting routine I''m still getting artifacts. The artifacts exist only for the first few frames that each particle is around, making it appear that my sort routine is getting it wrong to start with, but then, if you''ll excuse the bad pun, sorts itself out. Here''s the code of the callback function that compares two particles:

int _cdecl ParticleSortCB( const VOID* arg1, const VOID* arg2 )
CParticle *p1 = (CParticle*)arg1;
CParticle *p2 = (CParticle*)arg2;

FLOAT sx1 = p1->m_vecPos.x - vecCamera.x;
FLOAT sy1 = p1->m_vecPos.y - vecCamera.y;
FLOAT sz1 = p1->m_vecPos.z - vecCamera.z;

DOUBLE d1 = (sx1*sx1) + (sy1*sy1) + (sz1*sz1);

FLOAT sx2 = p2->m_vecPos.x - vecCamera.x;
FLOAT sy2 = p2->m_vecPos.y - vecCamera.y;
FLOAT sz2 = p2->m_vecPos.z - vecCamera.z;

DOUBLE d2 = (sx2*sx2) + (sy2*sy2) + (sz2*sz2);

// This was the original, simple comparison that works perfectly (for a fixed position camera):

// FLOAT d1 = p1->m_vecPos.z;

// FLOAT d2 = p2->m_vecPos.z;

if (d1 < d2)
return +1;

return -1;

It uses a^2+b^2+c^2=d^2 Pythagoras to calculate the distance of the particle from the camera. If the original comparison used in this callback function works perfectly, how come this one doesn''t? I''ve used DOUBLEs for extra precision, just in case that''s the problem, and algorithms don''t get much more straightforward than Pythag, so can anyone see what''s going wrong?

Thanks again!

Share this post

Link to post
Share on other sites
You want to leave z read normal (ZFUNC_LESSEQUAL or whatever) but disabled ZWriting when doing your particle system. This way the particles are still effected by the scene but don''t overwrite eachother.

Share this post

Link to post
Share on other sites
Yah, but you still end up with particles appearing ''in-front'' of particles that they shouldn''t when you disable the z-testing. This is not too tragic if the particles are small, but when you have expanding smoke trails, it can look awful.

The alpha test stuff only really works for fully transparent areas of the sprite. As soon as you try partial transparency it all falls back to having to depth-sort the scene.

There is a CG example of depth-independent transparency in the NVIDIA SDK that you might want to look at. I solved the problem using the x2+y2+z2=d2 sorting algorythm so didn''t spend much time checking out how they do it, but you may find it useful.

Share this post

Link to post
Share on other sites

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!