Talk:Blending: Difference between revisions
Making a section. |
Erichaines (talk | contribs) No edit summary |
||
Line 26: | Line 26: | ||
: Now, there may be specific cases (multi-compositing) where the destination alpha has a purpose. But in those cases, there is a second rendering operation that reads from the image that was written to. Which means the alpha has an explicit purpose, determined by the person viewing it. But without that context, no alpha can be said to be "incorrect" relative than another. That's why I added a section explaining about the blending of the alpha for the non-premultiplied case. [[User:Alfonse|Alfonse]] ([[User talk:Alfonse|talk]]) 11:48, 26 January 2016 (EST) | : Now, there may be specific cases (multi-compositing) where the destination alpha has a purpose. But in those cases, there is a second rendering operation that reads from the image that was written to. Which means the alpha has an explicit purpose, determined by the person viewing it. But without that context, no alpha can be said to be "incorrect" relative than another. That's why I added a section explaining about the blending of the alpha for the non-premultiplied case. [[User:Alfonse|Alfonse]] ([[User talk:Alfonse|talk]]) 11:48, 26 January 2016 (EST) | ||
:: I'm happy to see you left in my addition of "glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);". Better yet, in my opinion, is that this line should simply replace the one above it, "glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);" With the GL_ONE, GL_ZERO setting the alpha returned is always equal to the source alpha. The GL_ONE, GL_ONE_MINUS_SRC_ALPHA always gives the right answer, and as far as I know costs nothing extra (the compositor is hardwired on GPUs). If people don't care about the alpha, these new GL_ONE, GL_ONE_MINUS_SRC_ALPHA settings work. If people don't bother setting the destination alpha and simply leave it to be 1.0, these new settings work. If people do have an alpha set for the destination alpha, these new settings then give the proper blended alpha. The GL_ONE, GL_ZERO work for the first two cases, "don't care" and "return source alpha", but don't work for the last case. | |||
:: Let's put it another way. If "GL_ONE, GL_ONE_MINUS_SRC_ALPHA" was the original text on this page, what justification would there be to change it to "GL_ONE, GL_ZERO"? The only case I can see is where you want to return just the source alpha, in which case the right way to do this is to initialize the destination alpha to all zeros (along with initializing the destination color to all zeros, which is what you would do if you want just the source color for your cutout). I think it's worth teaching people the clear and consistent way to composite. |
Revision as of 00:35, 12 February 2016
Blending of Alpha
The text below is from http://www.realtimerendering.com/blog/gpus-prefer-premultiplication/ - once we get this page fixed, I'll remove it from my blog post.
I noticed that the OpenGL wiki's blending page I link to has an error. It says to use these settings if your source (and destination) is premultiplied:
glBlendEquationSeparate(GL_FUNC_ADD,GL_FUNC_ADD);
glBlendFuncSeparate(GL_ONE,GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ZERO); // not correct for the general case
This is not general - it assumes the destination's alpha is zero (which means the destination's fully transparent), as it simply sets the final alpha to be the same as the source alpha.
The proper settings are:
glBlendEquationSeparate(GL_FUNC_ADD,GL_FUNC_ADD);
glBlendFuncSeparate(GL_ONE,GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
This computes the final alpha as the source alpha's area plus the remaining area times the destination alpha's coverage, classic Porter & Duff. Might as well get it right since it costs nothing extra to compute. I tried to change the entry on the wiki, but it was reverted - discussion has commenced.
All the above said, I could be wrong - the OpenGL API for blending is one area that's tricky to understand, and I wouldn't at all be shocked if I'm misinterpreting here. GL_ONE,GL_ZERO to me means "multiply the source alpha by one, the destination alpha by zero", which would then mean you're saving just the source alpha, clearly incorrect if there's a destination alpha > 0.
- The question is this: what does the destination alpha actually mean? The meaning of a value is defined by how it gets used. And in most cases, the destination alpha in blending operations is *never used*. You can say that it means opaque or transparent, but if you're never using the framebuffer image's destination alpha (whether in a later blend operation or a fragment shader processing step or whatever), then it doesn't mean a thing. Most of the time, its value is meaningless and therefore it may as well be the source alpha of the last pixel rendered.
- Now, there may be specific cases (multi-compositing) where the destination alpha has a purpose. But in those cases, there is a second rendering operation that reads from the image that was written to. Which means the alpha has an explicit purpose, determined by the person viewing it. But without that context, no alpha can be said to be "incorrect" relative than another. That's why I added a section explaining about the blending of the alpha for the non-premultiplied case. Alfonse (talk) 11:48, 26 January 2016 (EST)
- I'm happy to see you left in my addition of "glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);". Better yet, in my opinion, is that this line should simply replace the one above it, "glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);" With the GL_ONE, GL_ZERO setting the alpha returned is always equal to the source alpha. The GL_ONE, GL_ONE_MINUS_SRC_ALPHA always gives the right answer, and as far as I know costs nothing extra (the compositor is hardwired on GPUs). If people don't care about the alpha, these new GL_ONE, GL_ONE_MINUS_SRC_ALPHA settings work. If people don't bother setting the destination alpha and simply leave it to be 1.0, these new settings work. If people do have an alpha set for the destination alpha, these new settings then give the proper blended alpha. The GL_ONE, GL_ZERO work for the first two cases, "don't care" and "return source alpha", but don't work for the last case.
- Let's put it another way. If "GL_ONE, GL_ONE_MINUS_SRC_ALPHA" was the original text on this page, what justification would there be to change it to "GL_ONE, GL_ZERO"? The only case I can see is where you want to return just the source alpha, in which case the right way to do this is to initialize the destination alpha to all zeros (along with initializing the destination color to all zeros, which is what you would do if you want just the source color for your cutout). I think it's worth teaching people the clear and consistent way to composite.