Results 1 to 9 of 9

Thread: AlphaBlend Formula/Algorithm

  1. #1

    AlphaBlend Formula/Algorithm

    Hello, guys!

    I'm using VCL's TBitmap with PixelFormat = pf32bit and using the 4st of the pixel byte as my alpha channel. Instead of using the TRGBQuad record of delphi, I'm using the following datatypes:
    [pascal]type
    PRGB32 = ^TRGB32;
    TRGB32 = packed record
    B, G, R, A : byte;
    end;
    [/pascal]
    Ok. It woks just fine and I can load and save bitmaps with a valid alpha channel.
    Now I'm trying to blend pixels using the alpha information, but the formula I'm usiging is producing a strange result. Could anyone, please, tell me a valid formula to blend pixels using alpha channel or say what I'm doing wrong? This is what my code looks like:

    [pascal]procedure TfrmCGScreen.DrawScene;
    var
    x, y, m : integer;
    p : PRGB32;
    begin

    //Just creating a background pattern...
    for x:=0 to fBuffer.Width-1 do
    for y:=0 to fBuffer.Height-1 do
    with fBufferFisrtLine[Y*fBufferLineLength+X] do
    begin
    B := 0;
    R := 0;
    A := 0;
    m := Tag div fBuffer.Height;
    case m of
    0 : B := ((x or y) + Tag) mod 255;
    1 : G := ((x and y) + Tag) mod 255;
    2 : R := ((x or y) + Tag) mod 255;
    else
    begin
    G := ((x xor y) + Tag) mod 255;
    tag := 0;
    end;
    end;
    end;

    //now I'm trying to blend the "fBlendImage" with the image in my backffuer
    for y:=0 to fBlendImage.Height-1 do
    begin
    p := fBlendImage.ScanLine[y];
    for x:= 0 to fBlendImage.Width -1 do
    begin
    with fBufferFisrtLine[Y*fBufferLineLength+ (X + (tag mod 600))] do
    begin
    B := B + p.B * p.A div 255;
    G := G + p.G * p.A div 255;
    R := R + p.R * p.A div 255;
    end;
    Inc(p);
    end;
    end;
    Tag := Tag+1;
    end;[/pascal]

    Thanks a lot!
    http://delphigames.blogspot.com/

  2. #2

    AlphaBlend Formula/Algorithm

    Let's say B is the background pixel and S is the sourcepixel and D is the destenation pixel.

    I would try this:

    [pascal]
    D.R := B.R + (S.R - B.R)*(S.A/255);
    D.G := B.G + (S.R - B.G)*(S.A/255);
    D.B := B.B + (S.R - B.B)*(S.A/255);
    [/pascal]

    It's just weighted interpolation.
    I've not tested this. Just made it up.

    Hope this helps....
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  3. #3

    AlphaBlend Formula/Algorithm

    Hey man, thanks for the fast reply!

    Your interpolation works only for the 100% black pixels on the alpha channel (A=255). Changing it for the code below, it works for the shades of gray too.

    [pascal]D.R := B.R + (S.R - B.R) * S.A div 255;
    D.G := B.G + (S.R - B.G) * S.A div 255;
    D.B := B.B + (S.R - B.B) * S.A div 255;
    [/pascal]
    http://delphigames.blogspot.com/

  4. #4

    AlphaBlend Formula/Algorithm

    Hmm.. ofcourse. Using / turns the result into a float, and the components of D are bytes.

    Does your sollution with DIV really work. DIV's result can only be an integer. :?
    I assume that your alpha value is a byte (0-255). So dividing it by 255, will give you a result inside the 0..1 range. If you use DIV, i assume all results in this range will be rounded to zero.

    I think this will be more accurate:

    Code:
    //Include the math unit to use "Floor"
    D.R := Floor(B.R + (S.R - B.R)*(S.A/255));
    D.G := Floor(B.G + (S.R - B.G)*(S.A/255));
    D.B := Floor(B.B + (S.R - B.B)*(S.A/255));
    Edit: I noticed you removed the brackets around "S.A div 255". I guess that'll make the difference. But could you try my snippet? I wonder wether it works.
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  5. #5

    AlphaBlend Formula/Algorithm

    [pascal]D.R := B.R + (S.R - B.R) * S.A div 255;
    D.G := B.G + (S.R - B.G) * S.A div 255;
    D.B := B.B + (S.R - B.B) * S.A div 255;
    [/pascal]
    This code definitely should work. Division is last operation there so there will not be any math errors. Using function to round float to int makes it just slower.

  6. #6

    AlphaBlend Formula/Algorithm

    Ok, thanks. Good to know.
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  7. #7

    AlphaBlend Formula/Algorithm

    User137 is rigth, chronozphere.

    As you ask me, I tested your other suggestion and it worked too (but the speed difference is very big between the two approaches).
    If you wanna see the code, you can download it here:
    http://www.fabianosalles.eti.br/blog...endTeste01.rar

    ps: use the '1' and '2' keys to switch between the calculations. Here in my machine it run with ~400fps, but as I'm using only GDI and VCL, the runtime speed may vary too much.

    Thanks
    http://delphigames.blogspot.com/

  8. #8

    AlphaBlend Formula/Algorithm

    Your demo looks really cool. I like the animated background.

    Switching between the modes doesn't make a real difference for me. The FPSses are varying between 380 and 420 (for both modes). It might be, because things like rounding and floating-point divisions are alot faster on my CPU than on yours. :?

    What CPU do you have and what kind of speed difference do you see in your FPSses? I have an AMD 2X 64 5400+.

    Thanks.
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  9. #9

    AlphaBlend Formula/Algorithm

    I run this last code only on the work computer and here I have a variation beteewn 490 and 520 fps, but when I swicth the "blend mode" ( :lol: ), it drops to ~300fps.
    http://delphigames.blogspot.com/

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •