1 person found this helpful
That's a great link, JJ, but I think I spotted an error. I don't think they have Screen blending represented correctly. If one actually screens two layers of pure white (both colors are 1), the math they show yields 0 (black). They're missing an outer 1 - (...).
Screen: result = 1 - ( (1 - top) * (1 - bottom) )
But that's a bit off-topic for this post.
As far as I know transparency doesn't change the pixel math at all, it just allows color from layers below to enter as an additional factor into the equation.
If your upper layer has partial transparency, then the result of adding the pixels in the layers together (as though there was no transparency) is then combined with some of the color from the layers below unchanged, per the amount of transparency of the top layer pixels.
Thus, assuming "bottom" means the color from below (simplest case, an opaque single layer), then your equation would be, for each of the channels:
result = ( opacity * (top + bottom) ) + ( (1 - opacity) * (bottom) )
For the integer modes, I believe the intermediate (top + bottom) result is capped at white if it exceeds white.
Thanks for your help. Yes, Noel, that's what I thought too, but it doesn't match the data from my test image. Here is the data:
// Bottom, top, top opacity, result
[0.2, 0.3, 1.0, 0.5 ],
[0.0, 0.25, 0.5, 0.125 ],
[0.0, 0.5, 0.5, 0.25 ],
[0.5, 0.5, 0.5, 0.75 ],
[0.75, 0.5, 0.5, 0.87451 ]
Sorry, I can't get the indentation right, I haven't learned how to do it, but it's the fifth row that doesn't fit my expectations:
Bottom layer: 0.75 (192)
Top layer: 0.5 (128)
Top opacity: 0.5 (128)
Result: 0.87451 (223)
This is double and triple checked in photoshop. The opacity of the top layer is created by adding a mask at 50% gray.
Your fifth line is the expected result when the intermediate result of (top + bottom) is clamped with a max of 1.
I will try to mock this up and see what I get, but at the moment I'm having problems with the latest beta ATI display driver.
I will add a few more tests to see if this is the correct answer. You are right, it does fit with the fifth line! It seems correct, will just add a few tests in a few minutes todouble check.
Okay, I've made more tests. It seems we have found the correct answer. So it is:
blendedValue = top + bottom
clamp blendedValue to [ 0, 1 ]
result = ( opacity * blendedValue) + ( (1 - opacity) * (bottom) )
Both Noel and conroy were helpful to find the answer, because my initial attempt was
result = bottom + ( opacity * top )
...which in the absense of clamping would be mathematically equivalent.
Thanks, and the your replies are marked as correct and helpful.