Sign in to follow this  
ShCiPwA

Blending with the color black?

Recommended Posts

I am currently trying to do somthing that seems pretty simple, but to my best efforts i cant seem to get it to work. I cant understand how to render the color black with blending enabled. For example, i have a particle system that can fade between a start color and an end color in the life of the particle. It also fades out as the particle gets older using the alpha channel. But it seems that the darker the color i assign the particles, the more transparent it gets, regardless of weather the alpha chan is 1 or not. Is it somthing to do with the clear color? I have tried many different BlendFunct combinations and i just cant seem to get a result. Thanks for your help, Spencer Rose.

Share this post


Link to post
Share on other sites
the blending function works like so:

in the graphics pipeline, a pixel gets drawn. Nothing fancy...
When blending is _disabled_ that pixel's colour gets written to the screen, overwriting the pixel that is already there.
HOWEVER, when blending is enabled, that pixel that is already in the backbuffer ('onscreen') does not get overwritten... Not yet.

The blend function is applied. And the result of that blend function overwrites the pixel on screen

That function looks like this:

colour = source * func_src + destination * func_dst.


In this case, 'source' is the pixel that has just been generated. Ie, the pixel that would be about to overwrite. 'destination' is the pixel that is currently on screen, ie, the pixel that was about to be overwritten.

func_src and func_dst are the values that you set with glBlendFunc()

Remember _both_ of source and destination are 4-component. Ie, RGBA.

So. For darkwings example, he has said gl_src_alpha, gl_one_minus_src_alpha, for func_src and func_dst which is alpha interpolation.

So... think about what they say... 'one minus src alpha'... (1 - source.alpha).

So... that means the blending equation is:


colour = source * (source.alpha) + destination * (1-source.alpha).


If the source was black, and alpha 1 (RGBA = 0001), then the output of that equation would be black. Work this out, it should make sense.

So... Further more, if you use that, and your particles are still invisible, then the output of that equation must not be changing from the current pixel on screen... ie, somehow, the equation is still outputting:

colour = destination..

so work that out above, and you get:

colour = source * 0 + desination * 1.

Do the maths, and you will see the only time that occurs is when source.alpha is zero.
So. that narrows the problem down, and means you need to look at:

the alpha component of your vertices,
the alpha of your textures, or any multitexturing, etc. (RGB textures default to alpha of 1 - white)
*important* the alpha of your _lighting_ (yes! lighting does effect alpha!) - generally it's best to set all lighting alpha terms to zero, except ambient material and global ambient to 1. _ESPECIALLY_ emissive, make sure emssive alpha is zero!

(normally, all these values above are multipled together to get the final result that becomes 'source', so if even one of them is zero, the output is zero)

So.
hopfully, that may shed some light on how blending works, and should help you debug your problem, and also will let you actually work out what is happening behind the scenes, so you can more accuratly get the effects you desire.

Have a look at all the different modes. There are quite a few. blending using destination (ie, current pixel on screen) can get some quite nice results (provided you know what your doing, which hopfully you now will)

cool.

have fun.


--- as an aside,
this should make it obvious why 'additive blending', ie, GL_ONE, GL_ONE works the way it does. This is the most common and fastest blending mode, for hopfully obvious reasons.



Graphics is not magic. It's maths. Cold hard unfeeling maths. Not warm fluffy magic.

Share this post


Link to post
Share on other sites
Thank you both, especially RipTorn :)
That clears up not only my problem, but any other queries i had on the topic of blending. Better info than most tutorials on the net (not to mention the OpenGL superbible)

A Good Particle System = Real Life
One day i will code it.

Thanks again.

Share this post


Link to post
Share on other sites
Just one more question.

I have since realised that if my desired blend func is on,(only fading with alpha) the black around my particles show back up (they are circles).
I have implemented a mask and it works perfectly with:
glBlendFunc(GL_DST_COLOR,GL_ZERO); // For mask
//Render quad here
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
//render particle with color over the top

Now I also have a lifetime alpha fade that now only fades the particle to black as the underlay mask layer stays at full opacity with the current blend func

What i need is a similar source factor to GL_DST_COLOR, but devided by alpha again, to fade the mask aswell :S

I cant think of a way to acheve this, with the same blend setup i need to render a black circle to the screen (on a quad) and yet keep the alpha to fade the black out. Could this be done with a double mask?

Thanks again

Share this post


Link to post
Share on other sites

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