exposions with particles look bad-FIXED BUT WHY ?!

Started by
15 comments, last by deffer 18 years, 9 months ago
Simply adding the alpha channel only sets it to 1.0f everywhere. So it's kind of pointless. Additionally, when you create the skybox texture, what pixel format do you use? Maybe the alpha channel is created automaticly.
If you want to test for the skybox texture having some weird alpha channel values, try rendering it with (GL_SRC_ALPHA, GL_ONE) (only for testing purpose).

Using (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) or (GL_SRC_ALPHA, GL_DST_ALPHA)with no alpha channels is the same as (GL_ONE, GL_ONE). So you got to rethink exactly what kind of effect you want to create (obviously, if you used one of the former, you were planning something else that you're doing, even if the final effect seems nice).

Quote:
I tried the replacement value GL_ONE_MINUS_SRC_ALPHA and it was worse !!


How it was worse? A shot would be nice...
Advertisement
it looked like this:

[html]
http://myweb.tiscali.co.uk/3drocknroll/explodeworse.bmp
[/html]

by the way here's the particle:

[html]
http://myweb.tiscali.co.uk/3drocknroll/particle.bmp
[/html]



Ok, Here's what I think is the suggested solution:

1. ensure alpha channel for the particle
2. alpha for black parts of particle should be set to 0.0f (totally see through)
3. the skybox should not have an alpha channel (it doesn't)



Did you try glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); ? maybe you have your alpha inversed - as in white=transparent?
Well I finally got it to work but have no idea why it does work !!

I did the following:

1. particle has an alpha channel - set to zero where pixel is black
2. skybox definitely does not have an alpha channel
3. Blend function that works is:

  glEnable(GL_BLEND);  glBlendFunc(GL_ONE, GL_ONE);//works !!  glEnable(GL_TEXTURE_2D);  glBindTexture(GL_TEXTURE_2D, m_texture);  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  //now set each particle's color and draw each particle


Can someone please explain why that works ?!
I don't even understand why that works and the ONE_MINUS_SRC_ALPHA doesn't.
I mean ONE_MINUS_SRC_ALPHA seems to be the correct one but it doesn't work.

cheers






Quote:Original post by ade-the-heat
it looked like this:
[*a picture*]


Now this is not worse. This is exactly as it is supposed to be - considering your particle has no alpha channel.


Quote:
1. ensure alpha channel for the particle
2. alpha for black parts of particle should be set to 0.0f (totally see through)
3. the skybox should not have an alpha channel (it doesn't)


3. - ok

1. and 2. - sure, but do it with a plan. A perfect solution would be to have an alpha channel just like the color intensity. To do that, I used standard DxTex.exe from DXSDK (I doubt you could download it elswhere, but I suppose any other graphic tool has similar option). There's an option "open onto alpha channel" which lets you use a texture of choice to build the alpha channel.
Then use (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) for normal blending, or (GL_SRC_ALPHA, GL_ONE) for additive blending.
And mission complete ;)

------
Alternatively:
You could use the fact that the particle is white-black, and practicly, you would want the alpha channel to be exactly as... blue. With GL_COMBINE_ARB, you can take alpha for the texture stage from the blue channel, instead of tha alpha channel.
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );{   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE );   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );   glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE );   glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_COLOR ); // <- alpha from color!   glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE );}glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//glBlendFunc(GL_SRC_ALPHA, GL_ONE);


I'm not sure about this, but I'm quite certain I was using something about that somewhere...

--------------
Alternatively:

Provide the texture in GL_INTENSITY format. Then use simply:
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // <- important: ONE for src//glBlendFunc(GL_ONE, GL_ONE);
glBlendFunc(GL_ONE, GL_ONE); means source (the particle) and destination (what's already been drawn) will just be added together, no matter what alpha is. This works fine, because the transparent parts of the particle are black (if you add black (0,0,0) to a color, you end up with the same color.) (Meaning you don't need an alpha channel if you do it this way.)

If you want to get cool looking fires/explosions etc. and use the alpha channel (which is good, since that means you can use black barticles if you need to) you can use glBlendFunc(GL_SRC_ALPHA,GL_ONE); (given that your particles have alpha zero where they are totally transparent and alpha one where they are totally opaque.)

You want GL_ONE as the second parameter for this effect, as this gives you an additive blending (making the particles look more like a single "thing" rather than separate particles.)

As for why you got the black boxes I can't say for sure.. I guess that some of the time the source and destination alphas were both one, meaning it worked, but some of the time they weren't for some reason (maybe the vertex color alpha was not always one and the destination alpha wasn't cleared to one) so it didn't work... Who knows?

I wouldn't disable depth test when drawing particles, by the way, only depth writes (glDepthMask(GL_FALSE).) Otherwise they will always be drawn in front of everything else..
Quote:Original post by ade-the-heat
Can someone please explain why that works ?!


You used additive blending. It's simply adds src to dst.
As it does not use the alpha channel, it was working. But it may not always be exactly as you want, as it tends to enlighten the scene. For explosions, it may be ok, but for smoke - not so much.

In the end, you may need the alpha version to work, too.

This topic is closed to new replies.

Advertisement