OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Apr 19, 2024 9:37 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: alpha blending
PostPosted: Mon Jan 02, 2017 10:40 pm 
Offline
Member
Member

Joined: Thu Apr 28, 2016 12:40 pm
Posts: 67
I am trying to alpha blend the window with the background, using this two formulas

Image

My blending code:
Code:
uint32_t blend_colors(uint32_t color1, uint32_t color2) {
    uint32_t alpha1 = GET_ALPHA(color1);
    uint32_t red1 = GET_RED(color1);
    uint32_t green1 = GET_GREEN(color1);
    uint32_t blue1 = GET_BLUE(color1);

    uint32_t alpha2 = GET_ALPHA(color2);
    uint32_t red2 = GET_RED(color2);
    uint32_t green2 = GET_GREEN(color2);
    uint32_t blue2 = GET_BLUE(color2);

    uint32_t r = (uint32_t)((alpha1 * 1.0 / 255) * red1);
    uint32_t g = (uint32_t)((alpha1 * 1.0 / 255) * green1);
    uint32_t b = (uint32_t)((alpha1 * 1.0 / 255) * blue1);

    r = r + (((255 - alpha1) * 1.0 / 255) * (alpha2 * 1.0 / 255)) * red2;
    g = g + (((255 - alpha1) * 1.0 / 255) * (alpha2 * 1.0 / 255)) * green2;
    b = b + (((255 - alpha1) * 1.0 / 255) * (alpha2 * 1.0 / 255)) * blue2;

    uint32_t new_alpha = (uint32_t)(alpha1 + ((255 - alpha1) * 1.0 / 255) * alpha2);
    uint32_t color1_over_color2 = (new_alpha << 24) |  (r << 16) | (g << 8) | (b << 0);
    return color1_over_color2;
}


before blending:
Image
after blending:
Image
Is there anything wrong with my code, the results looks odd. I was expecting it to look... more pretty :shock:


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Mon Jan 02, 2017 11:40 pm 
Offline
Member
Member
User avatar

Joined: Sun Sep 19, 2010 10:05 pm
Posts: 1074
If your color1 is your window color, and color2 is your background color, then you can probably just ignore Alpha2, at least for now. Your background alpha shouldn't affect the colors of any "layers" above it.

As for your window color, all you need is the ratio of window color to background color. The ratio is the window alpha color divided by 255.

Then, you just add the 3 weighted color components.

Code:
uint32_t blend_colors(uint32_t color1, uint32_t color2) {
    uint32_t alpha1 = GET_ALPHA(color1);
    uint32_t red1 = GET_RED(color1);
    uint32_t green1 = GET_GREEN(color1);
    uint32_t blue1 = GET_BLUE(color1);

    uint32_t red2 = GET_RED(color2);
    uint32_t green2 = GET_GREEN(color2);
    uint32_t blue2 = GET_BLUE(color2);

    float ratio = alpha1 / 255.0f;

    uint32_t red = (red1 * ratio) + (red2 * (1 / ratio));
    uint32_t green = (green1 * ratio) + (green2 * (1 / ratio));
    uint32_t blue = (blue1 * ratio) + (blue2 * (1 / ratio));

    uint32_t result = (255 << 24) |  (red << 16) | (green << 8) | (blue << 0);

    return result;

This should work fine for your case. Once you get that working, then you can add some logic for calculating the result alpha value, so that you can combine two non-background images, but it's a little more complicated, because you are going to have to make some decisions about how your alpha blending is going to work.

But let us know if that solves your immediate problem.

_________________
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Tue Jan 03, 2017 3:40 am 
Offline
Member
Member
User avatar

Joined: Thu Jul 12, 2012 7:29 am
Posts: 723
Location: Tallinn, Estonia
It _looks_ to me that you're picking background pixels from wrong locations. Are you sure you are getting the pixel data correctly? Esp from background window backing buffer.

_________________
Learn to read.


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Tue Jan 03, 2017 7:59 am 
Offline
Member
Member

Joined: Thu Apr 28, 2016 12:40 pm
Posts: 67
Thanks SpyerTL and dozniak !
I just fixed it
The formulas were correct, like dozniak said, I actually fetched the pixels at wrong location.
It looks good now =D> =D> =D>
Image


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Tue Jan 03, 2017 8:25 am 
Offline
Member
Member

Joined: Thu Apr 28, 2016 12:40 pm
Posts: 67
Moving window is significantly slowed down since the color of the moving window needs to be recalculated again at every move.
Any ideas how to deal with this?


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Tue Jan 03, 2017 8:59 am 
Offline
Member
Member

Joined: Wed Sep 19, 2012 3:43 am
Posts: 91
Location: The Netherlands
I'd probably only drag an outline of the window and then repaint the entire thing once movement has stopped/mouse has been released.


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Tue Jan 03, 2017 1:41 pm 
Offline
Member
Member
User avatar

Joined: Sun Sep 19, 2010 10:05 pm
Posts: 1074
Yep. Alpha blending is noticeably slow, unless you can get some hardware acceleration working for your specific video card.

The CPU just isn't powerful enough to calculate that many pixels without the user noticing.

You may want to look into writing this method in ASM (or in an assembly block), and using SSE extensions, which should make this code run around 4x faster, or more.

_________________
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Wed Jan 04, 2017 6:38 am 
Offline
Member
Member
User avatar

Joined: Wed Aug 17, 2016 4:55 am
Posts: 251
Just to make sure: it's not reading from the video memory but something from RAM, right? Because reading from video memory is the absolute worst thing you could ever do. And also make sure it's not just the emulator being slow.

Otherwise yeah, alpha blending is slow. You can try to optimize the blending function (huh, is that integer converted to float with separate multiplication and division (which can't be optimized away unless you use -ffast-math) and then more float divisions and then converted back to integer, on every pixel? x_x). Microoptimizing generally is not useful but in this case it'll be iterating over many thousands of pixels (or millions if the window is large enough) so you definitely want to speed it up as much as you can.


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Wed Jan 04, 2017 7:19 am 
Offline
Member
Member
User avatar

Joined: Thu Jul 12, 2012 7:29 am
Posts: 723
Location: Tallinn, Estonia
Afaik there are SSE/AVX functions to specifically help with this sort of thing (alpha blending), if you don't want to use asm you could use gcc intrinsics for that.

_________________
Learn to read.


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Wed Jan 04, 2017 8:28 am 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

Sik wrote:
Otherwise yeah, alpha blending is slow. You can try to optimize the blending function (huh, is that integer converted to float with separate multiplication and division (which can't be optimized away unless you use -ffast-math) and then more float divisions and then converted back to integer, on every pixel? x_x). Microoptimizing generally is not useful but in this case it'll be iterating over many thousands of pixels (or millions if the window is large enough) so you definitely want to speed it up as much as you can.


I'm not sure that I really want to mention it (because I prefer "correct" over "fast"); but with 8-bit integer alpha it's much faster to divide by 256 (when correct code would divide by 255). This allows you to do something like "out_blue = (blue1 * alpha) + (blue2 * ~alpha)) >> 8;".

Another (even faster) hack is to only use "50% alpha", so you can do something like "out_blue = (blue1 + blue2) >> 1;".

For 100% correct you need to take gamma into account and use "pow()". In practice this becomes something like "out_blue = gammaTable[ reverseGammaTable[blue1] * alpha + reverseGammaTable[blue2] * (1.0 - alpha) ];".


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Wed Jan 04, 2017 10:28 am 
Offline
Member
Member
User avatar

Joined: Sun Dec 25, 2016 1:54 am
Posts: 204
dozniak wrote:
Afaik there are SSE/AVX functions to specifically help with this sort of thing (alpha blending), if you don't want to use asm you could use gcc intrinsics for that.


SSE...

http://wm.ite.pl/articles/sse4-alphaover.html

AVX...

https://breeswish.org/blog/2015/07/26/avx2-alphablend/

_________________
Plagiarize. Plagiarize. Let not one line escape thine eyes...


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Wed Jan 04, 2017 10:48 am 
Offline
Member
Member
User avatar

Joined: Sun Dec 25, 2016 1:54 am
Posts: 204
more speed... MIT licensed.... well written...

https://github.com/skywind3000/BasicBit ... p_SSE2.cpp

worth a look if only for the 128bit memcpy

_________________
Plagiarize. Plagiarize. Let not one line escape thine eyes...


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Wed Jan 04, 2017 11:02 am 
Offline
Member
Member
User avatar

Joined: Wed Aug 17, 2016 4:55 am
Posts: 251
(writing ~ instead of the actual ASCII symbol because the forum's font makes it look like - instead)

Brendan wrote:
I'm not sure that I really want to mention it (because I prefer "correct" over "fast"); but with 8-bit integer alpha it's much faster to divide by 256 (when correct code would divide by 255). This allows you to do something like "out_blue = (blue1 * alpha) + (blue2 * ~alpha)) >> 8;".

That was pretty much my first post here lol

I think you got the calculation wrong though, because doing it that way means you can never get 255 (don't forget that shifting rounds down). It should be out_blue = ((blue1 * alpha) + (blue2 * ~alpha) + 255) >> 8. That +255 causes the entire range to be skewed so the extreme values always give the correct result after the shift. Also don't forget to make sure that ~ applies as a byte-sized value (hint: C will cast to int then apply ~ which won't be nice, so you better account for that).

And yeah it's not correct but if performance is an issue then better to have it look "somewhat" OK. Probably not worth the effort being correct until you can use the GPU to crunch numbers, making the UI feel more responsive to the user is more important than cosmetic details.

EDIT: right, I just remembered the other possible way to fix the calculation
out_blue = ((blue1 * (alpha + 1)) + (blue2 * ~alpha)) >> 8

That +1 may be more useful since it could end up compiled into an INC (also since you'd be using alpha+1 and ~alpha three times each, they're likely going to be computed once and stored into their own variables then their result reused).


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Thu Jan 05, 2017 8:22 pm 
Offline
Member
Member

Joined: Thu Apr 28, 2016 12:40 pm
Posts: 67
Does SSE works on emulators like QEMU and BOCHS ? I tried them before and didn't see much improvement.


Top
 Profile  
 
 Post subject: Re: alpha blending
PostPosted: Fri Jan 06, 2017 4:44 am 
Offline
Member
Member
User avatar

Joined: Tue Aug 02, 2016 1:52 pm
Posts: 286
Location: East Riding of Yorkshire, UK
szhou42 wrote:
Does SSE works on emulators like QEMU and BOCHS ? I tried them before and didn't see much improvement.

I think you can enable SSE and other extensions with the -cpu flag in QEMU. I'm unsure about Bochs though.

_________________
com.sun.java.swing.plaf.nimbus.InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState
Compiler Development Forum


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 108 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group