PDA

View Full Version : FBO and blending



yackies
05-19-2009, 06:59 AM
Hi,


I need to render a scene in an FBO : (some 2D image with alpha blending mode [glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)]
this FBO is rendered and blended with the same blending mode with other images....

if I draw in my FBO some image with glcolor4f(1,1,1,0.5); when the fbo is rendered it seeems that the the image is not at half the luminance, but 1/4 of the luminance.... it seems that RGB value are premultiplied by alpha. Is it normal ?

what can I do ? Is it a bug ?

Yack

overlay
05-19-2009, 09:59 AM
glBlendFunc() sucks when you try to do compositing (blend images)

because:

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) is equivalent
to:
glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ ALPHA,GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

The third argument will use alpha*alpha in the equation used to compute the alpha component of the FBO image. This is not a problem... until you blend this image on top of other images!


Use that instead:

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ONE_MINUS_SRC_ALP HA);

the third argument will use 1*alpha in the equation used to compute the alpha component of the FBO image.

For more details, read the "4.1.8 Blending" section of the OpenGL spec 2.1, page 208.

dletozeun
05-19-2009, 10:11 AM
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) is equivalent
to:
glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ ALPHA,GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);


As far as I understand, it is not. I think it is:

glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ ALPHA,GL_ONE,GL_ONE);

But I do not see how glBlendFuncSeparate could help here.

overlay
05-19-2009, 10:57 AM
Just read Spec 2.1, page 211:
"BlendFunc argument src determines both RGB and alpha source functions, while dst determines both RGB and alpha destination functions."



Suppose you keep the original glBlendFunc, (in addition, RGB and Alpha BlendEquations are set to FUNC_ADD (initial values) ):

R_d is the red component initially in the colorbuffer.
R_s is the red component of the fragment.
R is the red component at the end of the blending in the colorbuffer.

(I skip the green and blue component because this is exactly the same equation)

I use the same notation for alpha: A_d, A_s an A.

(BTW, this is the notation of table 4.1 on page 210 of Spec 2.1.)

R=R_s*(A_s)+R_d*(1-A_s) // OK (on the table, S_r=A_s and D_r=1-A_s)

A=A_s*(A_s)+A_d*(1-A_s) // first term is A_s^2 ! (on the table, S_a=A_s and D_a=1-A_s)
ie the wrong thing...


With
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ONE_MINUS_SRC_ALP HA);

you get the same equation for rgb, but for alpha:
A=A_s*(1)+A_d*(1-A_s) // on the table, S_a=1 and D_a=1-A_s

ie no more A_s^2.

R or A are what you have at the end in the FBO. Then, I guess "yackies" renders the colorbuffer in the default framebuffer by drawing a full quad with the colorbuffer of the FBO as a RGBA texture. This is when the problem is visible if you use glBlendFunc() only, because the alpha of this texture is wrong.

dletozeun
05-19-2009, 11:51 AM
My mistake! you are right overlay, I should have read the spec before! :p

yackies
05-19-2009, 12:20 PM
thanks a lot ... i will try this tomorrow.