1

The "normal" source-over blend equation is
outColor = srcAlpha * srcColor + (1 - srcAlpha) * dstColor

This equation does not consider the destination alpha, and as such produces poor results when the destination alpha is not 1.0.

For example, consider the case of a 50%-opaque yellow source color over a destination that is fully transparent, but has a red color. [Edit: e.g. the RGBA buffer has values of [255, 0, 0, 255] in each channel.] The above equation results in 50% yellow blended with 50% red, tainting the yellow even though the background is fully transparent.

What is a blend equation that works with destination alpha, such that a source image with semi-transparent pixels blended over a fully-transparent target remains unchanged?

Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • "*produces poor results when the destination alpha is not 1.0.*" It's not a matter of "poor results" or "good results". It's a matter of "what math do you want?" What does it mean for a destination color to have an alpha other than 1.0? For example, what does it mean for a surface to be both "fully transparent" (ie: completely see-through) and "red"? If a surface was "fully transparent", then it would have contributed no color to the underlying colors, right? So it didn't put "red" there; that must have come from other rendering. – Nicol Bolas Jan 12 '22 at 18:41
  • @NicolBolas I appreciate that it's all "just math". My expectation—which I believe others share—is that "normal" blending behaves like images printed on glass (with ink that can fully occlude light, where desired). If I have a Photoshop layer with semi-transparent pixels over NO background, or over a layer that is 100% transparent, the colors of the upper layer are not tainted. The same is true when saving such a layer as a 32-bit PNG: colors in the layer that are visible are not tainted by some invisible background color. – Phrogz Jan 12 '22 at 18:49
  • Related, and perhaps interesting: in a 32-bit PNG where the image is completely transparent, Photoshop writes RGBA values of `(0,0,0,255)`, i.e. "Transparent Black". This is rarely evident, except when texture interpolation in a 3D engine pulls the black into intermediary colors. This is what "transparent red" means: an RGBA buffer must have SOME values in the RGB channels, even if the alpha buffer is fully transparent. – Phrogz Jan 12 '22 at 18:52
  • 1
    A blend formula that takes destination alpha into account is given as answer in [Blend mode on a transparent and semi transparent background](https://stackoverflow.com/q/1724946/555045) – harold Jan 12 '22 at 19:04
  • 1
    @Phrogz: "*or over a layer that is 100% transparent*" If a layer is 100% transparent, then how did it write "red" to those colors? – Nicol Bolas Jan 12 '22 at 19:48
  • Thank you, @harold, for finding the duplicate question that I could not. Cheers! In the future, I suggest that you flag questions as a duplicate when you find a good duplicate like this. – Phrogz Jan 14 '22 at 00:41

1 Answers1

0

You should draw translucent objects from furthest to closest.

If you are going to draw N objects sorted by distance, when you render object i you only need take into account the alpha of i. All the alphas for objects < i have already been taken into account when they were drawn.

enter image description here

(image from: https://www.sterlingpartyrentals.com/product/color-gels-for-par-light/)

The dstAlpha is almost never used.

In your example, having transparent red in the destination... how was the red drawn in the first place if its fully transparent?

You should always draw fully opaque objects first, and make sure that the whole screen gets something opaque drawn in to it. In 3D you can for example use cubemaps for making sure that this is the case.

enter image description here

(image from: https://learnopengl.com/Advanced-OpenGL/Cubemaps)

tuket
  • 3,232
  • 1
  • 26
  • 41
  • I appreciate your desire and attempt to help, but you have not answered the question. Let me answer yours: "How was the red drawn in the first place?" It does not matter. With any RGBA buffer there must be SOME value in the RGB channels, even if the A channel is full of 0s. When the target buffer for a blend is an RGBA buffer, if it has 0 alpha and the source-over equation I listed is used, the colors of the source image will be tainted by the RGB channel in the target. Harold's comment on the question lists a valid duplicate with a correct answer to this question. – Phrogz Jan 14 '22 at 00:39