Question and suggestion about default blend mode

Started by Diarandor, August 30, 2021, 03:24:58 PM

Previous topic - Next topic
Hi! Although I'm not active these days, I have a question about the default blend mode.

The engine v1.6.x currently uses the following as default blend mode (called "blend"):
Quote"blend" (default): This drawable object is alpha-blended onto the destination surface.
dstRGB = (srcRGB * srcA) + (dstRGB * (1 - srcA))
dstA = srcA + (dstA * (1 - srcA))
Link to the Lua API: https://www.solarus-games.org/doc/latest/lua_api_drawable.html#lua_api_drawable_set_blend_mode

Why was this blend mode chosen? I do not like it because it is not associative, which is a bad property because this is not what happens in the real world. Let me explain this. In our real world, when you overlap 3 semitransparent surfaces A, B and C, the associative property
(A * B) * C = A * (B * C)
is satisfied, where "A * B" means putting or drawing A above B.

However, the "over" blending mode (https://en.wikipedia.org/wiki/Alpha_compositing) does satisfy the associativity, and is given by
newA = srcA + dstA - dstA * srcA      // This is equivalent to the current alpha in "blend".
newRGB = ( srcA * srcRGB + (1 - srcA) *  dstA *  dstRGB ) / newA.

Note that if newA is 0, the denominator in newRGB should be replaced by 1 (or whatever, because the new surface becomes transparent) to avoid a NaN error.

So these are my suggestions:
1) Add a new blend mode to the engine, called "over".
2) Set the "over" blend mode as default, if this does not produce incompatibilities with the old "blend" mode.

If you like the idea, we could open an issue for this. If there is a reason to keep "blend" as default, I would like to know, just by curiosity.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."