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
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev