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"):
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
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
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.
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.Link to the Lua API: https://www.solarus-games.org/doc/latest/lua_api_drawable.html#lua_api_drawable_set_blend_mode
dstRGB = (srcRGB * srcA) + (dstRGB * (1 - srcA))
dstA = srcA + (dstA * (1 - srcA))
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
Code Select
(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
Code Select
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.