Re: [AD] memory bitmap blending

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


On Sat, 2008-11-29 at 10:36 +1100, Peter Wang wrote:

> Here are screenshots of what I see for the first three.
> (low quality to avoid spamming the list)
> 
> src=INVERSE_ALPHA, dest=ONE
>     src is mysha, a=0.0, so there should be a contribution
>     from mysha right?
> 
> src=INVERSE_ALPHA, dest=INVERSE_ALPHA
>     a=0.0, so the contribution from both should be full
> 
> Unless I'm misunderstanding how the blending should work?
> 

I think it was mostly Trent and me who came up with the blending - we
probably should revisit this after getting some more opinions.

The current specification is here:

http://alleg.sourceforge.net/naturaldocs/files/src/tls-c.html#al_set_blender

And it's very simple:

r = dr * dst + sr * src * color.r
g = dg * dst + sg * src * color.g
b = db * dst + sb * src * color.b
a = da * dst + sa * src * color.a

And it's of course wrong. In the next paragraph, there is a claim that
with these formulas we could achieve alpha blending by doing:

al_set_blender(ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, {1, 1, 1, 1})

However, look at an example where the source pixel is

sr,sg,sb,sa = 1,1,1,0.5 (50% transparent white)

And the destination pixel

dr,dg,db,da = 0,0,0,1 (opaque black)

We get:

src = 0.5 (because of ALPHA setting)
dst = 0.5 (because of INVERSE_ALPHA setting)

r = 0 * 0.5 + 1 * 0.5
g = 0 * 0.5 + 1 * 0.5
b = 0 * 0.5 + 1 * 0.5
a = 1 * 0.5 + 0.5 * 0.5

That is, in the target bitmap we put (0.5,0.5,0.5,0.75). A gray pixel
with 75% transparency, which makes no sense. If the alpha of the
destination is ignored, it coincidentally gives an expected result,
that's why it wasn't completely obvious.

I think now, the formulas need to be:

r = dr * dst + sr * src * color.r * color.a
g = dg * dst + sg * src * color.g * color.a
b = db * dst + sb * src * color.b * color.a

And the destination alpha is not modified at all.

This also gives color.a a much more intuitive meaning, if it is set to
0.5 instead of 1 then whatever was drawn before is now drawn at half
transparency.

For the (much less common) case where the destination alpha needs to be
modified we need an extra variable, which probably should switch to the
current state. Something like:

al_set_alpha_blender()

maybe?

-- 
Elias Pschernig <elias@xxxxxxxxxx>





Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/