2
$\begingroup$

I'm struggling with understanding how blending works. Here's what I understand: when I set the following

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

then I would expect to have the following result when blending $scr$ with $dst$: $$ result = src.a \cdot src + (1-scr.a) \cdot dst $$ This is the blending function setup I commonly stumble upon. My problem is the following: when I have a completely opaque background, let's say $dst=(1,0,0,1)$, and I render a half opaque square in front of it $src=(0,1,0,0.5)$ then the resulting alpha for the new color will be $$ result.a = src.a \cdot src.a + (1-src.a) \cdot dst.a = 0.5 \cdot 0.5 + 0.5 \cdot 1 = 0.75 $$ How does it make sense to have a half opaque object in front of a fully opaque object result in something that is not fully opaque again? I feel like I'm misunderstanding something, I'm glad for any help I can get.

$\endgroup$
4
  • $\begingroup$ Check the correct blending equations. en.wikipedia.org/wiki/Alpha_compositing $\endgroup$
    – user1703
    Commented May 15, 2023 at 11:56
  • $\begingroup$ I've seen the equations on Wikipedia, but how would I need so set up the blend function to produce the same output as the equations found in Wikipedia? $\endgroup$
    – Bartolini
    Commented May 15, 2023 at 14:50
  • $\begingroup$ Double check what glBlendFunc does (both in the manual and numerically). $\endgroup$
    – user1703
    Commented May 15, 2023 at 15:01
  • $\begingroup$ I once wrote a lengthy answer about how to compose blending operations. $\endgroup$
    – Wyck
    Commented May 18, 2023 at 4:28

1 Answer 1

4
$\begingroup$

How does it make sense to have a half opaque object in front of a fully opaque object result in something that is not fully opaque again?

The problem here is one of concepts. The alpha component of a color has no inherent meaning. It doesn't mean opaque or transparent. It's just a value.

It only takes on a meaning when you use it in a way that gives it that meaning. Your blending function performs linear interpolation between the source and destination colors based on the source's alpha component. One way to conceptualize this equation is to say that the source alpha represents the opacity of the source color overlaid on top of the destination color.

However, this understanding of your blending equation only makes sense if we assume that the destination color is opaque. That is, you're always blending between a possibly transparent source and a definitely opaque destination.

So what does the destination alpha mean in this equation? Nothing. It's just data in your framebuffer. It has no inherent meaning within the context of this blending operation.

So how would I set up the function to produce an alpha value which stays fully opaque when blended with a fully opaque color?

By using separate blending parameters for the alpha. The RGB and A components of the output color can be processed with separate parameters (or even equations):

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);

This will leave the destination alpha untouched.

$\endgroup$
4
  • $\begingroup$ Ok but to my understanding the resulting alpha value can be interpreted as the opacity/transparency of the image when saved to the file. So how would I set up the function to produce an alpha value which stays fully opaque when blended with a fully opaque color? $\endgroup$
    – Bartolini
    Commented May 15, 2023 at 14:49
  • $\begingroup$ @Bartolini: "Ok but to my understanding the resulting alpha value can be interpreted as the opacity/transparency of the image when saved to the file." Well, that's between you and the file format you're using. That's got nothing to do with OpenGL. I'll answer the rest in the answer. $\endgroup$ Commented May 15, 2023 at 17:10
  • $\begingroup$ There are just two uses of the alpha channel: premultiplied or non-premultiplied. AFAIK, the non-premultiplied is the rule in file formats. The OpenGL manual details the proper parameters to pass to the glBlendFunc function. $\endgroup$
    – user1703
    Commented May 15, 2023 at 17:25
  • $\begingroup$ Thank you very much guys, I think this clears it up for me! $\endgroup$
    – Bartolini
    Commented May 15, 2023 at 21:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.