Particle alpha blending

Started by
15 comments, last by theagentd 9 years, 6 months ago

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]

Advertisement

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)?

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.


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?

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

[attachment=24095:example3.jpg]

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.

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.

This topic is closed to new replies.

Advertisement