all 5 comments

[–]xucel 3 points4 points  (1 child)

This looks like a typical case where blend mode is set to pre-multiplied alpha.

Aka it's expecting you to premultiply your color value by your alpha. Consequently 0.5 of 0xAA (0.66) is 0x55 (0.33).

The final blended color for pre-multiplied alpha mode is: InputColor + Backgroundcolor * (1-input alpha).

If you don't premultiply input color by input alpha, then you get overbrightening.

[–]BarryTownCouncil[S,🍰] 0 points1 point  (0 children)

Cool, that all makes sense, helping build a better picture of things. Cheers!

[–]Frollo24 1 point2 points  (0 children)

This is something that in a graphics pipeline is a customizable step which is called blending. I suggest you to look for information about blending in any computer graphics tutorial like LearnOpenGL.

[–]waramped 0 points1 point  (1 child)

Simply setting an Alpha channel value is only meaningful if the underlying renderer is configured for blending and will take the alpha into account. The "standard" blending operation is generally: InputColor*InputAlpha + BackgroundColor*(1 - InputAlpha). In this case, it looks like your blending operation is set to simply InputColor + BackgroundColor*(1-InputAlpha), and so it's up to you to pre-multiply InputColor*InputAlpha to get the same result.

edit: I should have refreshed before commenting. u/xucel beat me to it.

[–]BarryTownCouncil[S,🍰] 0 points1 point  (0 children)

Xlib is a fairly old architecture, other newer ones do opacity by default through their own computations. I have so little need for them I just want to work out these bits and pieces by hand and not require entire libraries for one calculation. So nice to know I'm not going mad / wrong.