[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Public WebGL] Premultiplied alpha blending and issues with color accuracy

So I'm working on a prototype of Sketcher, as mentioned in previous posts, and I think I might've run up against a major roadblock when it comes to alpha blending.

I'm superimposing many brush images onto a texture. The images are generated by a fragment shader. I had my pipeline set up for premultiplied alpha earlier, since this was easy to work with, but with only 8 bits per channel to work with, color accuracy was visibly suffering, so I switched to unpremultiplied alpha, and saw immediate improvement.

I now run into a problem, and it's a classic one: I cannot find a way of making blendFuncSeparate() take both source and destination alpha into account for the color. This is a problem because the color underneath the alpha matte on my destination layer is bleeding through the soft edges of the brush.

Some Googling reveals that there is an extension, OES_texture_float, which would provide enough accuracy for premultiplied alpha, but there are some problems with this approach:

- not supported on every OpenGL ES implementation
- support for float texture FBOs is optional
- increased texture footprint

Something tells me that it would typically be mobile devices that would not support the extension, and of those that do, most would not support writing to the texture, and I'm guessing that support is not universal even on desktop computers.

In the Java version of Sketcher, I did alpha blending as follows:

	dA = dA + sA * (1 - dA)
	dC = dC + (sC - dC) * sA / dA

These are serial calculations, so dA in the 2nd equation refers to the final destination alpha, i.e. result of the 1st equation.

The 1st equation is a sort of cumulative alpha blend which interpolates between the destination and 1.0 using the source, so that compositing 0.5 over 0.5 gets you 0.75.

This was easily implemented in WebGL using:

	glBlendFuncSeparate(?, ?, gl.ONE_MINUS_DST_ALPHA, gl.ONE);

The 2nd equation interpolates between the destination and source color using the source alpha, but with the twist of dividing the source alpha by the final destination alpha first.

It's been too long since I worked these equations out, so I don't really understand why the 2nd equation works, except that the result never overflows, granted that I use fixed point arithmetic and a special case for divide by 0.

It's not critical that the WebGL version of Sketcher mixes colors in the same way, but if I'm going to do this with unpremultiplied alpha, the equation will need to take both source and destination alpha into account to avoid the color bleeding.

I tried to look into using multi-textures and a shader to do my own blending, but it would seem that I'm only allowed to use a single texture unit at any given point, and I need 2 to do blending.

It would seem that my problem is impossible to solve with the available tools. I hope that someone can prove me wrong.


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