Log in

View Full Version : OT: Alpha Blending


Blight
13th August 2002, 09:29
A bit out of topic,

I'm trying to think of the fastest way (non-asm/mmx) to do Integer Based Alpha Blending.

You have 2 RGB images and one 8-bit Alpha Image to controls the mix between the two images.

The best thing I could come up with is:

DestPixel = (Pixel1*(255-AlphaPixel)+Pixel2*AlphaPixel) / 255;

This keeps everything within the integer range, is there a better way I'm overlooking?

You could replace the "/ 255" with "shr 8", but then you'd lose 1/256 accuracy which I don't want.

trbarry
13th August 2002, 13:57
If the Alpha pixel had to be stored in a single byte then maybe you would be better of with only 129 Alpha values, 0-128.

DestPixel = (Pixel1*(128-AlphaPixel)+Pixel2*AlphaPixel) / 128

Then you could still shift accurately, or do it fast in MMX. But I just got up and haven't had enough coffee yet, so maybe I'm missing something. ;)

- Tom

dividee
13th August 2002, 16:35
What about that:
DestPixel = Pixel1 + ((Pixel2 - Pixel1) * AlphaPixel) / 255;
or even:
DestPixel = Pixel1 + (((Pixel2 - Pixel1) * AlphaPixel) * 257) >> 16;
(257 is approx. 65536/255)

Blight
13th August 2002, 18:25
trbarry:
Range isn't optional, it's an 8bit value.

dividee:
"DestPixel = Pixel1 + ((Pixel2 - Pixel1) * AlphaPixel) / 255;" Exact same speed as my original foruma, I guess the compiler optimizes it to match.

"DestPixel = Pixel1 + (((Pixel2 - Pixel1) * AlphaPixel) * 257) >> 16;" Inaccurate, similar inaccuracy to just shifting.

dividee
13th August 2002, 18:39
Inaccurate? It shouldn't be. Probably a rounding problem:
DestPixel = Pixel1 + (((Pixel2 - Pixel1) * AlphaPixel) * 257 + 32768) >> 16;

gabest
13th August 2002, 21:22
Nothing beats premultiplied colors with invertedly stored alpha channel :)

DestPixel = (Pixel1*iAlphaPixel >> 8) + Pixel2;