PNG alpha channel problems

Started by Akril15, Tue 19/02/2013 03:39:43

Previous topic - Next topic

Crimson Wizard


Crimson Wizard

Quote from: Snarky on Fri 13/09/2013 09:26:38
Code: AGS
combined_rgb = (front.rgb * front.alpha + back.rgb * (1 - front.alpha) * back.alpha) / combined_alpha;  // Now verified


<...>
I believe if you switch to this formula, it should also take care of the magic pink problem without any special case code.

<...>
Edit: I've had a chance to think it over, and also check with Wikipedia (see the final formula in the Description section), and yes, this is the correct formula.

Okay, with this formula I am combining translucent Gui & Button sprites and the results are identical to what I see in graphic editor (I use Paint.Net) when I make 2 translucent layers over 1 opaque one. If I do not make final division (by combined alpha) the result has something in common, but with relatively darker colors (less brightness?).

But now I got two different troubles:
1) When opaque control color is drawn on opaque gui color, result is pitch black. Translucent colors combine with opaque fine.
2) When translucent control color is drawn over gui pixels with zero alpha (e.g. magic pink 0x00FF00FF) the result is opaque.
Maybe I made some silly mistake in algorythm implementation...

Snarky

Yeah, I think there must be an implementation error somewhere there.

Code: AGS
combined_alpha = 1 - (1-front.alpha)*(1-back.alpha);
combined_rgb = (front.rgb * front.alpha + back.rgb * (1 - front.alpha) * back.alpha) / combined_alpha;


1) If front.alpha = 1 (opaque), then combined_alpha = 1-0 = 1, and combined_rgb = (front.rgb * 1 + 0) / 1 = front.rgb. So the result should be the front color. (Back color or opacity shouldn't matter, since all those terms go to 0.) Must be a mistake somewhere in the code.

2) If back.alpha = 0 (completely transparent), then combined_alpha = 1 - (1-front.alpha)*(1-0) = 1 - 1 + front.alpha = front.alpha. So the combined opacity should just be the front opacity. However, from that hex value, it looks like the magic pink pixels don't in fact have zero alpha, but are set to opaque (which I guess is the whole point of magic pink; I thought it was stored internally with 0 opacity, but that doesn't seem to be the case), so yeah, it's not going to work. I think you will have to add a special case line of code to treat magic pink with opacity 1 as having opacity 0. (I think this is a bit of an ugly hack, and that in 32-bit games we should just use the alpha channel instead of relying on "magic pink", but I guess that's the way AGS works.)

Crimson Wizard

#43
Quote from: Snarky on Mon 16/09/2013 10:08:42However, from that hex value, it looks like the magic pink pixels don't in fact have zero alpha, but are set to opaque (which I guess is the whole point of magic pink; I thought it was stored internally with 0 opacity, but that doesn't seem to be the case)
No, it has opacity (alpha) = 0. The format is ARGB with blue being the lower byte and alpha being the highest byte...
So 0x00FF00FF is:
A: 00
R: FF
G: 00
B: FF:

EDIT: corrected myself.

Crimson Wizard

#44
Okay, I found the mistake that produced unexpected black color.

Regarding magic pink (eurgh!), this was simply because the Gui sprite did not have alpha channel. Well.. it technically was 32-bit image, but the sprite was marked as not having alpha-channel, and AGS just blended it as opaque surface over room.

To make things even more confusing, the Gui which does not have background image at all, but has background color set to transparent, works properly (translucent buttons are rendered as translucent over room background).
I feel like this:
(wtf)?????????

Anyway, this is another issue and should be dealt with separately.

E: For now I am glad to tell that Col. Knox'es Inventory works well both in its original and modified way (without gInvBackground).

Snarky

Quote from: Crimson Wizard on Mon 16/09/2013 10:16:50
The format is ARGB with blue being the lower byte and alpha being the highest byte...
So 0x00FF00FF is:
A: 00
R: FF
G: 00
B: FF:

What, you mean you need to mix TWO colors to get magenta on an RGB screen?! :-D Maybe I should think before posting...

Nice work, CW! I'm pleased as punch to have alpha-blending of multiple layers working properly at last.

Crimson Wizard

#46
Just a small note,

this:
Code: text

combined_alpha = 1 - (1-front.alpha)*(1-back.alpha);

is algebraically (sp?) equivalent to
Code: text

combined_alpha = front.alpha + back.alpha * (1-front.alpha);

The latter formula is given on wiki page. It is also slightly faster to calculate.

Snarky

Sure, I just gave it in the form that corresponds to how it was logically derived, since that seemed like it would be more obvious.

(The idea is to think of transparency as the fraction of light from below "passing through" the layer to the eye, so if you have multiple layers you multiply the fractions together: If one layer is 1/2 transparent and the other layer 1/3 transparent, together they are 1/6 transparent, for example. So you get combined_transparency = front.transparency * back.transparency. The rest is just the conversion to opacity: alpha = 1 - transparency.)

Crimson Wizard

#48
@General Knox
Regarding your grass-cutting minigame -
http://www.adventuregamestudio.co.uk/forums/index.php?topic=47666.msg636467623#msg636467623

I found that this happens only with WFN fonts (TTF work properly). One silly mistake in 3.3.0. Will be fixed in the next build.

Knox

Quote from: Crimson Wizard on Tue 17/09/2013 20:44:54
@Colonel Knox
Regarding your grass-cutting minigame -
http://www.adventuregamestudio.co.uk/forums/index.php?topic=47666.msg636467623#msg636467623

I found that this happens only with WFN fonts (TTF work properly). One silly mistake in 3.3.0. Will be fixed in the next build.


Ah no I got demoted to Colonel, hehe. Nice, things are really moving along! :grin:
--All that is necessary for evil to triumph is for good men to do nothing.

Crimson Wizard


Crimson Wizard

#51
I kinda feel myself an idiot now, because all those formulas were in Calin Leafshade's AGSBlend plugin.
The advantage of these are that they process all pixels in one loop, while Allegro drawing calls a function for every pixel, which may affect perfomance in the long run (ironically, the Allegro's loop itself is written is assembler).
Slight disadvantage is that Calin's are not optimized in the same way as Allegro's algorythms are (for instance he multiplies/divides on 255, while there's a way to work with 256 (which should be converted to bitwise shift by compiler, which is way faster) while loosing half-of-percent in color precision (which is not a big deal with 32-bit colors and AA anyway).

I am now thinking about implementing all those nice Calin's blending modes, maybe in the next subrelease, like 3.3.1 or something (yeah I still hope we can make 3.3.0 a release candidate, heh).

Knox

Quote from: Crimson Wizard on Sat 21/09/2013 17:16:58
I am now thinking about implementing all those nice Calin's blending modes, maybe in the next subrelease, like 3.3.1 or something (yeah I still hope we can make 3.3.0 a release candidate, heh).

Bah, just put 'em in 3.3.0, hehe! :grin:
--All that is necessary for evil to triumph is for good men to do nothing.

Crimson Wizard

Alright, I pushed an update to repository, keeping fingers crossed. :tongue:

Calin Leafshade

I just looked at the commit and i have to say *FINALLY*.

Excellent work CW.

Knox

Quote from: Calin Leafshade on Thu 26/09/2013 05:28:57
I just looked at the commit and i have to say *FINALLY*.

Excellent work CW.

...you implemented Calin's AGSBlend plugin? :shocked:
--All that is necessary for evil to triumph is for good men to do nothing.

Crimson Wizard

Quote from: Knox on Fri 27/09/2013 12:02:19
Quote from: Calin Leafshade on Thu 26/09/2013 05:28:57
I just looked at the commit and i have to say *FINALLY*.

Excellent work CW.

...you implemented Calin's AGSBlend plugin? :shocked:

No, (not yet). Just proper default alpha blending for now.

Knox

Hey Crimson!

Beta 8 fixed all the alpha problems I've been having, yay! I can now set Visual settings to Multiplied Translucence + Proper Alpha Blending and everything works great. :grin:

Do you know if there is a way currently to get semi-transparent alpha sprites working on the "text window gui", other than having to use pain-in-the-butt work-arounds? I've got a shadow on my text window but it isn't drawing properly from what I tested so far (minor minor issue though, for the time being I can just not use the shadow).

--All that is necessary for evil to triumph is for good men to do nothing.

Crimson Wizard

#58
Quote from: Knox on Wed 02/10/2013 04:30:05
Do you know if there is a way currently to get semi-transparent alpha sprites working on the "text window gui", other than having to use pain-in-the-butt work-arounds? I've got a shadow on my text window but it isn't drawing properly from what I tested so far (minor minor issue though, for the time being I can just not use the shadow).

To clarify: you have a sprites with alpha set as TextWindow gui parts (corners & center), or you have something that casts shadows upon TextWindow?
Thinking about this, I could have missed the text window drawing when was fixing the gui alpha blending. I am going to check this.
E: Also - dialog options!

Knox

Yep, that's what I meant. I have semi-transparent shadows under the text window (so the corners and sides have semi-transparent shadows, the center is opaque).

Want me to send you an example of the text window sprites?

PS: You're really awesome, by the way, fixing all these issues. :=
--All that is necessary for evil to triumph is for good men to do nothing.

SMF spam blocked by CleanTalk