Reputation: 363
Here's a simple spike showing my problem:
<html>
<head>
<title>Clear Color</title>
<style type="text/css">
#stage {
background-color: rgba(127,127,127,1);
}
</style>
</head>
<body>
<canvas id="stage" width="100", height="100"></canvas>
<script type="text/javascript">
var options = {
alpha: true,
premultipliedAlpha: true
};
var ctx = document.getElementById("stage").getContext("webgl", options);
ctx.clearColor(1, 0, 0, 0);
ctx.enable(ctx.BLEND);
ctx.blendFuncSeparate(
ctx.SRC_ALPHA, ctx.ONE_MINUS_SRC_ALPHA,
ctx.ONE, ctx.ONE_MINUS_SRC_ALPHA
);
ctx.clear(ctx.COLOR_BUFFER_BIT);
</script>
</body>
</html>
The blendFunc is this:
(sR*sA) + (dR*(1-sA)) = rR
(sG*sA) + (dG*(1-sA)) = rG
(sB*sA) + (dB*(1-sA)) = rB
(sA*1) + (dA*(1-sA)) = rA
...which translates to this (I think):
(1*0) + (0.5*(1-0)) = 0.5
(0*0) + (0.5*(1-0)) = 0.5
(0*0) + (0.5*(1-0)) = 0.5
(0*1) + (1.0*(1-0)) = 1.0
Why am I seeing a light pink canvas instead of just the grey that the CSS declares? The pink is obviously coming from my clearColor, but why is it showing the red when the alpha component is 0?
Upvotes: 4
Views: 4617
Reputation:
WebGL by default requires your colors to use premultiplied alpha. 1,0,0,0 is an invalid color because rgb of (1,0,0) * alpha of (0) = 0,0,0 not 1,0,0 so it's an invalid color and the spec is undefined for invalid colors. The results will be different on different browsers.
You have a few options
Tell WebGL your colors are not premultiplied
gl = canvas.getContext("experimental-webgl", { premultipliedalpha: false });
Get rid of the alpha channel
gl = canvas.getContext("experimental-webgl", { alpha: false });
Premultiply your alpha
var r = 1;
var g = 0;
var b = 0;
var a = 0;
gl.clearColor(r * a, g * a, b * a, a);
similarly in your shaders either pass in premultiplied colors or premultiply at the end.
gl_FragColor = vec4(color.rgb * color.a, color.a);
Your blending settings have no effect. They only used when you call gl.drawXXX
, they are not used when the canvas is composited with the background.
Upvotes: 6