Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » Colors behaving differently than expected

This thread is locked; no one can reply to it. rss feed Print
Colors behaving differently than expected
Eric Johnson
Member #14,841
January 2013
avatar

I made a mock-up of three circles overlapping one another in GIMP, each with its opacity set to 50%. See the first attachment for the results.

Then I drew the same three circles in Allegro 5 using al_draw_filled_circle(), each with its alpha set to 128. However, the Allegro 5 results were different than what I got from GIMP. See the second attachment.

Here's my code:

#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_primitives.h> 3 4int main(void) { 5 6 al_init(); 7 8 al_init_primitives_addon(); 9 10 ALLEGRO_DISPLAY *display = al_create_display(256, 256); 11 12 al_clear_to_color(al_map_rgb(255, 255, 255)); 13 14 al_draw_filled_circle(80, 144, 64, al_map_rgba(255, 255, 0, 128)); 15 al_draw_filled_circle(144, 80, 64, al_map_rgba(255, 0, 0, 128)); 16 al_draw_filled_circle(144, 144, 64, al_map_rgba(0, 0, 255, 128)); 17 18 al_flip_display(); 19 20 al_rest(5); 21 22 al_destroy_display(display); 23 24 return 0; 25}

So what's the deal? I expected Allegro to generate the same result as GIMP, but it's different. Why is this?

Aaron Bolyard
Member #7,537
July 2006
avatar

Allegro uses pre-multiplied alpha by default. You'd need to multiply the color channels by the fractional alpha (e.g., 0.5). Otherwise, you get an additive effect.

http://liballeg.org/a5docs/trunk/graphics.html#al_premul_rgba_f

http://liballeg.org/a5docs/trunk/graphics.html#al_set_blender

Chris Katko
Member #1,881
January 2002
avatar

I would love if Allegro had a tutorial / explaination of the reasoning for the different blending modes, and why pre-multiplied is the default. That's something I've never understood.

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

Eric Johnson
Member #14,841
January 2013
avatar

Thanks for linking to the docs, Aaron. I'm with Chris on this one; I'm curious to know the reason for using pre-multiplied alpha by default as well.

Elias
Member #358
May 2000

Just looking at ex_premulalpha should be enough reasoning - without pre-multiplied alpha it leads to incorrect results, with pre-multiplied alpha it leads to the correct results.

The explanation is simple. When OpenGL interpolates it does linear interpolation on all channels. So lets say you draw a texture where one pixel is opaque red (red = 1, green = 0, blue = 0, alpha = 1). And the pixel next to it is completely transparent black (red = 0, green = 0, blue = 0, alpha = 0). Now you scale this up enough that OpenGL has to interpolate a pixel between those two - it will therefore be:

red = (1 + 0) / 2 = 0.5
green = (0 + 0) / 2 = 0
blue = (0 + 0) / 2 = 0
alpha = (1 + 0) / 2 = 0.5

So far, there is no difference between normal and pre-multipled alpha. Now OpenGL draws that pixel, lets say on a completely black background (red_back = 0, green_back = 0, blue_back = 0).

The result is:

result_red = red_back * (1 - alpha) + red * alpha = 0 + 0.5 * 0.5 = 0.25
result_green = 0
result_blue = 0

We drew a pixel that is 25% red instead of a pixel that clearly should be 50% red, as it is exactly between the completely red and the completely black one! So, just like you can see in ex_premul_alpha, it appears wrong.

What if we use pre-multiplied alpha?

result_red = red_back * (1 - alpha) + red = 0 + 0.5 = 0.5
result_green = 0
result_blue = 0

Now we get the correct 50% red between the full red and the full black pixel.

In a way the problem is just that with not pre-multiplied alpha there is very many ways to specify transparent colors, e.g. 0/0/0/0 and 1/1/1/0 are both the exact same 100% transparent color. But one will darken everything when interpolating to it and the other will interpolate everything to white - and there is no way to simply interpolate towards transparency.

--
"Either help out or stop whining" - Evert

amarillion
Member #940
January 2001
avatar

I have to agree with Chris - this is the bit where I had most difficulties porting allegro 4 games to allegro 5. They way blending works is different and hard (at least for me) to wrap my head around.

--
Martijn van Iersel | My Blog | Sin & Cos | Tegel tilemap editor | TINS 2017

Go to: