|
From: Maxim S. <mcs...@ya...> - 2004-06-18 22:00:17
|
> I think you're wrong assuming only top alpha counts. Consider the case > of bottom alpha to be 0. This is by implication an invalid or undefined > color. If by pure chance the bottom color resembles black, you're > blending to black background, where as you really should just assign > the top color to the pixel ignoring the bottom color completely. The > situation stays the same for increasing bottom pixel alpha, the > influence of the bottom color should be wheighted by the bottom alpha. > Of course for rgb24, you're code is absolutely correct, as there is no > such thing as bottom pixel alpha. For rgba32, there should be an > additional case. Absolutely convincing :) So, I'll work on it. First, I thing we'll need to make it right, then make it fast. I must admit I'm very bad in formulae if I don't see any physical meaning of them. So, as far as I understand, the background alpha should work as if we look through a completely transparent glass, drawing with permanant markers on it. So that, initially, RGB and alpha are 0, that is, fully transparent. The background alpha (opacity) cannot decrease ever, it can only become more and more opaque. So, if we achieved 255, there's no way to make it transparent again. As for calculating the RGB values, I think, Stephan's method is correct. My only doubt is that the following formulae from SVG are correct too, but they don't consider the canvas (background or bottom) alpha either: Er, Eg, Eb - Element color value Ea - Element alpha value Cr, Cg, Cb - Canvas color value (before blending) Ca - Canvas alpha value (before blending) Cr', Cg', Cb' - Canvas color value (after blending) Ca' - Canvas alpha value (after blending) Ca' = 1 - (1 - Ea) * (1 - Ca) Cr' = (1 - Ea) * Cr + Er Cg' = (1 - Ea) * Cg + Eg Cb' = (1 - Ea) * Cb + Eb I know what the problem is. SVG uses premultiplied alpha, that is, alpha alpha is already *in* colors. The top (or element) colors must be premultiplied too, that is, you cannot have, say, R=255, G=0, B=0, and A=0. That's incorrect because in the permultiplied colorspace the components cannot have values greater than alpha. I must admit AGG uses some messy combination of regular and premultiplied methods. We'll need to clean it up and I think there should be both, reguilar and premultiplied colorspaces. So, if we finally come up with some good method, combining the correct model, Stephan's gamma correction method and Marc's speed it'll be just great! McSeem |