Problem Description
Hi! I'm creating a WebGL 2.0 vector shapes renderer and I'm facing a serious problem that I don't know how to resolve. My current rendering pipeline looks like this:
- I'm drawing shapes in my shaders with premultiplied colors in linear RGB space.
- When two shapes overlap I'm blending them (either in shaders or in render passes) using
blendEquationSeparate(FUNC_ADD,FUNC_ADD); blendFuncSeparate(ONE,ONE_MINUS_SRC_ALPHA,ONE,ONE_MINUS_SRC_ALPHA );
. See the link to learn more why: http://www.realtimerendering.com/blog/gpus-prefer-premultiplication - After all the shapes are drawn, the colors of the final buffer are unpremultiplied, converted to sRGB space, and premultiplied again. It results in premultiplied sRGB color space, which is what the browser want for me (as far as I am aware).
However, it seems that the browser does the alpha blending in sRGB space instead (not linear one). This gives very strange results, especially on big, transparent areas (that I need). In order to clearly see the problem, consider the screenshot below:
What you see here is a red circle on 2 green backgrounds. The green background on the right side of the picture is a background composed in my shaders in a linear sRGB space. The background on the left side of the picture is just an HTML website. As you can see, my color blending is correct (do not have dark transition pixels). More info about why blending in linear space is the correct one is here: http://www.realtimerendering.com/blog/?s=srgb
Here is a more convincing example - it's a shadow. Top of the image is composited in linear RGB (correct way), the bottom is composited by Chrome in sRGB space (incorrect way):
Unfortunately, it seems that the browser composer works in sRGB space. Even if we do 2 divs, they are blended in the wrong way
.circle{
position:absolute;
background:#ff0000;
width:100px;
height:100px;
text-align:center;
-webkit-border-radius: 50px;
-moz-border-radius: 50px;
border-radius: 50px;
}
.circle2{
position:absolute;
margin-left:40px;
background:#00ff00;
width:100px;
height:100px;
text-align:center;
-webkit-border-radius: 50px;
-moz-border-radius: 50px;
border-radius: 50px;
}
<div class="circle"> </div>
<div class="circle2"> </div>
Question
The question is simple - are we able to somehow ask the browser (I'm asking both for cross-browser as well as a browser-specific solution) to blend the WebGL canvas with the HTML in the background in linear RGB space?