• Advertisement
Sign in to follow this  

Particle alpha blending

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

I want to render some soft round particles. Currently I'm rendering white quads with an alpha value calculated as:

float alpha = 1.0f - clamp(length(position), 0.0f, 1.0f);

The blending function looks like:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

But the particles seem to subtract from each other around the outside (dark halo):

 

[attachment=24091:example.jpg]

Share this post


Link to post
Share on other sites
Advertisement

Are you sorting the particles by depth and rendering them back-to-front?

 

These aren't 3D particles. Just a bunch of random 2D sprites.

Share this post


Link to post
Share on other sites

Are you sure the RGB channel is fully white. Have you deactivated the depth buffer?

 

The code is basically just:

 

float alpha = 1.0f - clamp(length(position), 0.0f, 1.0f);
frag_color = vec4(1.0f, 1.0f, 1.0f, alpha);

 

There is no depth buffer, depth test is disabled.

Share this post


Link to post
Share on other sites

Feels like exact moment to try premultiplied alpha.

At least blending should be additive to avoid that darkening.

Edited by vstrakh

Share this post


Link to post
Share on other sites

I don't understand what the issues is. Isn't this blending mode the equivalent of:

new_color = lerp(current_color.rgb, old_color.rgb, current_color.a);
Edited by Chris_F

Share this post


Link to post
Share on other sites

There's plenty of blending modes. Interpolation is just one of them, and it looks like not suitable for this case.

 

If the functionality of GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA was identical to the code I posted, then I would not be having the issue displayed in my image.

Share this post


Link to post
Share on other sites

This is realy weird. I'm 99% sure that the operation is associative if all particles have the same solid color.

Have you tried rendering the image without alpha blending just to be sure? From the fragment shader you have posted, this should not be the problem but you never know...

Could this be a backbuffer precision error?

Edited by Madhed

Share this post


Link to post
Share on other sites

I don't really know what you mean. If I disabled alpha blending all I'm going to have is a bunch of white quads.

 

Here is a screenshot from another program where I render random rectangles (not using OpenGL, using software rendering) in which I calculate the alpha value the exact same way and perform the blending new_color = lerp(current_color.rgb, old_color.rgb, current_color.a); As you can see there are no dark edges.

 

[attachment=24093:example2.jpg]

Edited by Chris_F

Share this post


Link to post
Share on other sites

I tried to draw some random quads with your fragment shader.

I got white blobs without dark halos.

 

[attachment=24094:blending.jpg]

 

Are you sure blend equation is GL_FUNC_ADD, and no intermediate fbo's involved (will affect alpha)?

 

 

Share this post


Link to post
Share on other sites

I don't think you're actually getting dark halos. I think it's kind of an optical illusion.  It's caused by the color gradient change of the light when it reaches the edge. Try squaring the alpha value like this:

float alpha = 1.0f - clamp(length(position), 0.0f, 1.0f);
frag_color = vec4(1.0f, 1.0f, 1.0f, alpha*alpha);

See if it looks more like you expect.

Share this post


Link to post
Share on other sites


Are you sure blend equation is GL_FUNC_ADD, and no intermediate fbo's involved (will affect alpha)?

 

I was using an intermediate FBO with a GL_RGBA16F format. I'm thinking the issue is I need to disable blending when rending the fullscreen quad from the FBO to the default FB?

Share this post


Link to post
Share on other sites

OK, here is what it looks like when I disable blending on the fullscreen pass and square the alpha.

 

[attachment=24095:example3.jpg]

Share this post


Link to post
Share on other sites

So, there is fbo :)

It's ok to disable blending if that image is final.

But if you need all particles combined in image, and that image needs resulting alpha (to be combined with scene), then you'll have to use premultiplied alpha.

Share this post


Link to post
Share on other sites

You can do blending in the fullscreen pass as well, but you need to change the blend function you use when rendering the particles.

 

The problem is that with the most common blend mode (glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)), you accidentally square the source alpha, resulting in incorrect destination alpha. This can be avoided by using

 

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

 

instead. This should give the resulting FBO correct alpha values.

 

EDIT: Also, in the fullsceen copy pass, your pixels essentially have premultiplied color, so glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) is the correct one to use.

Edited by theagentd

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement