[Public WebGL] Compositing with HTML

Chris Marrin [email protected]
Fri Jan 8 10:03:45 PST 2010

I'm confused (as usual) about premultiplied alpha and compositing with the HTML page. By default, the pixels in the WebGL canvas are premultiplied. If I make a WebGL canvas and clear it to (0.5,0,0,0.5) I believe this background is 100% red, with an alpha of 50%. If it, for instance, blends with a page background of white (1,1,1), the resultant pixels will be (1,1,1) * 0.5 + (0.5,0,0), or (1,0.5,0.5). This will look like washed out red, and I think that's the right result. Doing this test on both WebKit and Firefox seems to give this result.

But if I clear the canvas to (1,0,0,0.5), I think I've made an error. The resultant color would be (1.5,0.5,0.5). Now assuming you clamp, you'd get a result that looks right in that case. But if you put this color over (0.5,0.5,0.5), you'd get (1.25, 0.25, 0.25) which clamps to (1, 0.25, 0.25). But when clearing to (0.5,0,0,0.5), you get a result of (0.75, 0.25, 0.25). So in the former case, the red would be too bright.

If you do this test in WebKit it seems to do the right thing. Over white the clear color looks the same because of clamping, but over other colors the red is too bright. But if you do this in Firefox, it looks wrong. Over white, you get gray! In fact, any red component over 0.5 gives you the same result. So it looks like when Firefox gets a color component over 1.0, it replaces the entire color with black or something. Is this a bug in Firefox?

But the bigger issue for me is how confusing all this premultiplied alpha business is. When drawing fragment colors, I can used (1.0,0,0,0.5) just fine because I am using a blendFunc of (ALPHA, ONE_MINUS_ALPHA). This says that the incoming colors are not premultiplied, so they should be multiplied by  alpha. The confusing thing is that the clearColor doesn't seem to obey the blendFunc.

Interestingly, the 2D Canvas API doesn't have any notion of clearing the background (maybe for this exact reason). And in that API, colors in the canvas are all premultiplied. So, to clear the canvas to a given color you essentially draw a rectangle in that color. The clear color you specify is not premultiplied, but the result in the color buffer is.

Maybe there's nothing we need to do here. But we at least need to make a notation that clearColor does not obey the blendFunc and the values you specify go into the color buffer directly, so you need to take this into account if your color buffer is premultiplied.

[email protected]

You are currently subscribe to [email protected]
To unsubscribe, send an email to [email protected] with
the following command in the body of your email:

More information about the public_webgl mailing list