PDA

View Full Version : Blending problem



spider853
02-15-2013, 01:04 AM
Hi,
Have some blending problem,
so I'm using this to making some manipulation only on the silhouette of character, but looks like the color src func also counts the alpha. The image alpha is opaque after blending.


bm.set_blend_equation(CL_BlendEquation::cl_blend_e quation_add, CL_BlendEquation::cl_blend_equation_add);
bm.set_blend_function(CL_BlendFunc::cl_blend_one, CL_BlendFunc::cl_blend_one_minus_src_alpha, CL_BlendFunc::cl_blend_one, CL_BlendFunc::cl_blend_zero);


shouldn't it be like:
Orgb = Srgb * 1 + Drgb * (1 - Sa)
Oa = Sa * 1 + Da * 0 ;
?
in this equation it should keep the source alpha rather than making it opaque.

btw, I'm drawing Sprites

Judas
02-15-2013, 09:56 AM
I don't see any error in your math or how you call the two functions.

However, keep in mind that source in this case is the sprite and dest is the frame buffer. You are overwriting the current frame buffer alpha with the alpha in the sprite image.

spider853
02-15-2013, 12:33 PM
Isn't blending suppose to be performed on fragment and then applied to framebuffer which should not overwrite the alpha channel if the alpha is from source?
I get the white background from sprite opaque.

if I change first BlendFunc to cl_blend_zero then alpha is ok, but if is cl_blend_one then alpha is opaque. (sprite alpha that is overlayed)
as I understand the first function should not influence the alpha as its performed only on RGB right?

rombust
02-16-2013, 10:04 AM
I can't answer you question, but ensure that you are using clanGL and not clanGL1 or clanSWRender for clanlib 2.3.

OpenGL 1.3 doesn't support separated blend modes.

spider853
02-16-2013, 10:52 AM
yep, its CL_SetupGL setup_gl;
#include <ClanLib/gl.h>
CL_DisplayWindow
CL_GraphicContext

as far as I know this uses the latest OGL

videocard gtx680

Judas
02-16-2013, 03:47 PM
Yes, the blending operation is running on a per fragment level. But the fragment is the source, the frame buffer is the destination. Your blend function copies the alpha value from the source (the fragment color, aka your sprite) to the frame buffer alpha.

It sounds like you actually want the opposite. To keep the frame buffer alpha value and ignore the sprite alpha. In that case the blend function becomes:



bm.set_blend_function(CL_BlendFunc::cl_blend_one, CL_BlendFunc::cl_blend_one_minus_src_alpha, CL_BlendFunc::cl_blend_zero, CL_BlendFunc::cl_blend_one);

spider853
02-16-2013, 05:39 PM
I want to keep the alpha sprite, I mean where is the sprite transparent to be visible the current image in framebuffer (background)

here are some pictures of the problem:

(top image) bm.set_blend_function(CL_BlendFunc::cl_blend_one, CL_BlendFunc::cl_blend_one_minus_src_alpha, CL_BlendFunc::cl_blend_zero, CL_BlendFunc::cl_blend_one);

(middle image) bm.set_blend_function(CL_BlendFunc::cl_blend_one, CL_BlendFunc::cl_blend_one_minus_src_alpha, CL_BlendFunc::cl_blend_one, CL_BlendFunc::cl_blend_zero);

(bottom image) bm.set_blend_function(CL_BlendFunc::cl_blend_zero, CL_BlendFunc::cl_blend_one_minus_src_alpha, CL_BlendFunc::cl_blend_one, CL_BlendFunc::cl_blend_zero);

1732

I can get alpha to work only when the source rgb is cl_blend_zero which should not affect the alpha.


P.S. I kind of solved this problem by modified clanlib to allow me to extract texture from sprite and use a shader for this, but still want to know what I did wrong with blend.

Judas
02-18-2013, 02:45 AM
Ah, you just want standard normal alpha = transparency.

The blend mode for blending a normal (not multiplied) alpha texture with a pre-multiplied alpha frame buffer is as follows:


bm.set_blend_function(cl_blend_alpha, cl_blend_one_minus_src_alpha, cl_blend_one, cl_blend_one_minus_src_alpha);

This produces the following math:


framebuffer.rgb = fragment.a * fragment.rgb + (1-fragment.a) * framebuffer.rgb
framebuffer.a = 1 * fragment.a + (1-fragment.a) * framebuffer.a

The blend mode for blending a pre-multiplied alpha texture with a pre-multiplied alpha frame buffer is:


bm.set_blend_function(cl_blend_one, cl_blend_one_minus_src_alpha, cl_blend_one, cl_blend_one_minus_src_alpha);

The math is:


framebuffer.rgb = 1 * fragment.rgb + (1-fragment.a) * framebuffer.rgb
framebuffer.a = 1 * fragment.a + (1-fragment.a) * framebuffer.a

spider853
02-22-2013, 03:11 PM
Ah, I see, thanks