Skip to main content
GameDev.net gamedev.net
🔒 Locked

Alpha blend formula?

Started by Ziggy5000 Dec 18, 2000 at 11:18 AM 7 replies 25.5k views
Original Post
Ziggy5000
Ziggy5000
What is the exact alpha blending formula (on a per-pixel and r,g,b component basis)? How would one do other effect like Lighten or Luminosity? I want to write an MMX/3DNOW/SSE optimized routine for each but do not know the basic math... Thanks, ill-lusion.com
ziggy@ill-lusion.com
laxdigital.com
[email=ziggy@laxdigital.com]ziggy@laxdigital.com[/email]
Tom
Tom
Here is the alpha-blending formula:

color = alpha * src + (1 - alpha) * dest

// optimized, it would look like this:
color = alpha * (src - dest) + dest

// my actual alpha-blending code looks like this:
__stdcall int BlendColors (double alpha, int src, int dest)
{
int r1 = (src >> 16) & 0xFF;
int g1 = (src >> 8) & 0xFF;
int b1 = src & 0xFF;
int r2 = (dest >> 16) & 0xFF;
int g2 = (dest >> 8) & 0xFF;
int b2 = dest & 0xFF;
int ar, ag, ab;

ar = int(alpha * double(r1 - r2) + r2);
ag = int(alpha * double(g1 - g2) + g2);
ab = int(alpha * double(b1 - b2) + b2);

return ab | (ag << 8) | (ar << 16);
}

I hope that's enough to get you started! I also have formulas for extracting HSR values instead of RGB, so if you'd like them, just post again or e-mail me.

Edited by - Tom on December 18, 2000 12:27:10 PM
GDNet+. It's only $5 a month. You know you want it.
LilBudyWizer
LilBudyWizer
If you do ((alpha*(src-dest))/255)+dest or the close enough version of ((alpha*(src-dest))>>8)+dest you can get rid of the floating point and use a one byte integer for the alpha.
Keys to success: Ability, ambition and opportunity.
karmalaa
karmalaa
quote:
Original post by LilBudyWizer

If you do ((alpha*(src-dest))/255)+dest or the close enough version of ((alpha*(src-dest))>>8)+dest you can get rid of the
floating point and use a one byte integer for the alpha.




Please note that ''alpha'' need to be scaled in the (discrete) range [0, 255] in such a case. Tom''s code used an alpha value in the (continous) range [0, 1].





[home page] [e-mail]

---
"Lifting shadows off a dream once broken
She can turn a drop of water into an ocean"
---[home page] [[email=karmalaa@inwind.it]e-mail[/email]]
biskit
biskit
Look, you can further optimize the algorithm by making the alpha value an integer between 0-255. The algorithm would be like this:

destRed = (alpha * (destRed-srcRed)) + destRed;
destGreen = (alpha * (destGreen-srcGreen)) + destGreen;
destBlue = (alpha * (destBlue-srcBlue)) + destBlue;

This is faster because you don''t have to convert from double(or float) back to an integer. I would recommend checking out John Herbert article at http://www.gamedev.net/reference/programming/features/mmxblend/.


----------------------------------------
Implementation is everything. Period.
Particle Toast
----------------------------------------Implementation is everything. Period.
Tom
Tom
That code I posted is older than I thought. You should use floats instead of doubles, since you don''t need that much accuracy. If you store alpha as a byte, you will need to divide it by 255 for this algorithm to work.

Also, Direct3D (and OpenGL?) requires color values in the range of 0 to 1. That''s why I recommend using floats all around. It depends mostly on what graphics API you use, if any.
GDNet+. It's only $5 a month. You know you want it.
LilBudyWizer
LilBudyWizer
Just a thought, but it seems that if he is needing a formula for doing an alpha blend then he isn''t using DirectX or OpenGL to do it for him. Perhaps it is just my monitor, that I run with the contrast/brightness turned down or perhaps I''m slightly color blind but I can''t see a differance between the color (0,0,0) and (1,1,1). So while it may be strictly correct to divide by 255 I would divide by 256 so it can be done in a shift.
Keys to success: Ability, ambition and opportunity.
DigitalDelusion
DigitalDelusion
quote:
Original post by LilBudyWizer

Just a thought, but it seems that if he is needing a formula for doing an alpha blend then he isn''t using DirectX or OpenGL to do it for him. Perhaps it is just my monitor, that I run with the contrast/brightness turned down or perhaps I''m slightly color blind but I can''t see a differance between the color (0,0,0) and (1,1,1). So while it may be strictly correct to divide by 255 I would divide by 256 so it can be done in a shift.


1) I don''t think youre color blind.
2) Actually the formula won''t loose it''s correctness either, you can use any value you want the only reason for using 255 or 256 is that in 24bpp you can only have 256 diffrent levels of intensity anyway if we had 48bpp modes we would probably use 65535 instead of 255. Not that anyone would see a differance... but anyway it would work all the same.

HardDrop - hard link shell extension."Tread softly because you tread on my dreams" - Yeats
Tom
Tom
Just a thought, but it seems that if he is needing a formula for doing an alpha blend then he isn''t using DirectX or OpenGL to do it for him.

Not necessarily. I wrote this alpha-blending algorithm for use with DirectDraw back in the day, before I knew how to use Direct3D for 2D effects. But you''re probably right.

Perhaps it is just my monitor, that I run with the contrast/brightness turned down or perhaps I''m slightly color blind but I can''t see a differance between the color (0,0,0) and (1,1,1). So while it may be strictly correct to divide by 255 I would divide by 256 so it can be done in a shift.

That''s not such a good idea, because then you will never have an alpha value of pure 1.0, which is completely opaque. This won''t matter under normal circumstances, because the difference is so subtle (1/256th), but if you start throwing out contrast processes (if you''re making an art program, for example), then the difference can become very noticeable.

Anyway, use whatever works for you.
GDNet+. It's only $5 a month. You know you want it.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.