c++colorssfmlalphablendingblending

SFML blending mode to interpolate colors with alpha


Assume I have a C_1 = (255, 0, 0, 127) filled sf::Texture and a sf::RenderTexture filled with C_2 = (0, 0, 0, 0). Then I call

render_texture.draw(texture);

The result given by sf::BlendAlpha is a texture filled with (127, 0, 0, 127), but my goal (for the small graphics editor app I'm writing) is blending those two colors to get (255, 0, 0, 127), because, intuitively, drawing on perfectly transparent texture is "copying color of your brush to it". I've checked formulas of sf::BlendAlpha, and it appeared to work like this:

C_res = C_src * aplha_src + C_dst * (1 - alpha_src)

Where C_src is C_1 and C_dst is C_2. But wait, does it totally ignore aplha_dst?

If I understand blending right, the formula I need is something like

alpha_sum = alppha_src + alpha_dst
C_res = C_src * alpha_src / alpha_sum + C_dst * alpha_dst / alpha_sum

Which gives adequate colors and does not ignore alpha_dst. But with BlendingMode from SFML, using different Factors and Equations, there's no chance to get division (that also introduces troubles when dealing with alpha_sum = 0). Any suggestions on how actually I should think about blending colors and painting? At least, did I get it right, that usual alpha blending used by SFML is not what graphics editors do? (tested on Aseprite, Krita, Photoshop, they blend color from the brush to (0, 0, 0, 0) as I expect)


Solution

  • The solution I ended up with: writing your own blend mode with glsl and using shaders. This way you can create and formulas without the need to think about how to bring it to sfml, because it already supports shaders, that can be easily passed to any draw call.