> Why? I can see no value in beeing accurate here, because:
> a) The error of dividing by 256 instead of 255 gives you an
>    amplitude error of 0,4%. Nobody will see this - never.
>
> b) You are not accurate at all. You are doing integer division,
>    without rounding. This will give you another 0,2% (max).

Wolfgang - thanks for your excellent comments!

In looking much further into alpha blending and optimizations,
I agree with you.  The original integer alpha blend contained
two multiplies and one divide:

bg = (a*fg + (255-a)*bg)/255;

This can be rearranged algebraically without loss of any accuracy to
one multiply and one divide:

bg = ((a*(fg-bg))/255 + bg;

Finally, the divide can be replaced by an increment and
shift, providing 92% accuracy, and still exact at alpha 0
and 255.  This is very fast and accurate for the fully
translucent and opaque cases:

bg = ((a*(fg-bg+1))>>8 + bg;

I have tested all the above, and developed a macro
for the alpha blend using:

#define muldiv255(a,b)    (((a)*(b)/255)    /* slow divide*/
#define muldiv255(a,b)    (((a)*(b+1))>>8) /* fast, 92% accurate*/

allowing the alpha blend to take a very fast form:

bg += muldiv255(a, fg-bg);


> If accuracy is a problem, why not doing:
> alpha *= 257; // alpha == 0..65535
> color = (alpha * fg + (65535-alpha) * bg) >> 16;

Good idea.  However, the above muldiv255 is faster with one
less multiply.  All these methods, including yours, are
compared in an interesting article:

http://my.opera.com/Vorlath/blog/2006/12/20/project-v-advanced-alpha-blending


> An optimized loop will look very different, with very much code 
> duplication....

Agreed.

Regards,

Greg



---------------------------------------------------------------------
To unsubscribe, e-mail: nanogui-unsubscr...@linuxhacker.org
For additional commands, e-mail: nanogui-h...@linuxhacker.org

Reply via email to