Jaakko Hyvätti wrote:
Hi all,I wonder if anyone has any thoughts about this? Is my solution, to define a new glBlendFunc for software renderer, the only one for this problem or are there less invasive solutions? Any thoughts on if this extension would be acceptable to Mesa code? :-) Jaakko If OpenGL is used for creating images with transparency, and images and drawing primitives are rendered on transparent background, the OpenGL Blending functions in standard do not blend the colours correctly. In case the background is completely transparent, and a semitransparent (translucent) colour or image is drawn on top of that, the usual Blending Function behaves incorrectly: glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); The extended version of this common function fixes the problem with incorrect Alpha values in the resulting image, but fails to fix the color channels: glBlendFuncSeparateEXT (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); The color channels are mixed with these settings with this formula: (Example for Red) Rd = destination Red Ad = destination Alpha Rs = source Red As = source Alpha R' = result destination Red A' = result destination Alpha A' = As + (1 - As) * Ad R' = As * Rs + (1 - As) * Ad Example: As = 0.5 Rs = 0.8 Ad = 0 Rd = 0.2 R' = As * Rs + (1 - As) * Ad = 0.5 * 0.8 + 0.5 * 0.2 = 0.5 This is incorrect, the correct R' is obviously 0.8, because Ad = 0, and Rd should not affect the resulting colour at all!
I'm not sure I agree with this. I've used glBlendFuncSeparate() in the past to do over/under compositing and it works just as it should.
Note: I agree that glBlendFunc() is insufficient for over/under compositing in some situations because the A value needs to be computed differently than RGB.
I think the confusion is whether you want the resulting image to be in premultiplied, or non-premultiplied format. It sounds like you want the later. That's actually fairly uncommon.
In your example above, if you use over-compositing consistantly, it'll never be the case that Ad=0 and Rd=0.2.
Are you really trying to do compositing with non-pre-multiplied colors? If so, is there a reason why pre-multiplied colors can't be used?
The solution is to compute the R' by weighing the Rs and Rd with their alphas relative to resulting alpha: R' = As/A' * Rs + (1-As/A1) * Rd R' = 0.5/0.5 * 0.8 + (1-0.5/0.5) * 0.2 = 1 * 0.8 + 0 * 0.2 = 0.8 This is correct. These patches create extension GL_FORECA_blend_relative that introduces Blending Functions GL_SRC_ALPHA_RELATIVE_FORECA and GL_ONE_MINUS_SRC_ALPHA_RELATIVE_FORECA that can be used to implement the latter formula: http://www.iki.fi/hyvatti/sw/Mesa-6.4.2-ext-foreca.diff http://www.iki.fi/hyvatti/sw/Mesa-6.5-ext-foreca.diff Use this to set the correct blending function: glBlendFuncSeparateEXT (/* sfactorRGB */ GL_SRC_ALPHA_RELATIVE_FORECA, /* dfactorRGB */ GL_ONE_MINUS_SRC_ALPHA_RELATIVE_FORECA, /* sfactorA */ GL_ONE, /* dfactorA */ GL_ONE_MINUS_SRC_ALPHA); Both generic and reasonably optimized version of the function is implemented.
I'm hesitant to put this into Mesa because I doubt anyone else will ever use it and I doubt any hardware would be able to implement it directly.
If you have any interest in hardware acceleration, I believe you might be able to do what you want by combining your images using textures and a fragment program.
-Brian ------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid0709&bid&3057&dat1642 _______________________________________________ Mesa3d-dev mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mesa3d-dev
