drawbot icon indicating copy to clipboard operation
drawbot copied to clipboard

How does alpha value addition work?

Open frankrolf opened this issue 7 years ago • 8 comments

In this example, I would expect the rectangle in the middle to be white, by overlaying alpha values that add up to 1. However, this is not the case (the rectangle remains grey-ish, which makes me assume it still is transparent to a certain degree).

rect(0, 0, width(), height())
margin = 100
number_rects = 4
alpha = 1 / number_rects
for _ in range(number_rects):
    fill(1, 1, 1, alpha)
    rect(margin, margin, width() - 2 * margin, height() - 2 * margin)

Is it naïve to assume adding up alpha values works in a linear fashion? (This is not necessarily a DrawBot problem, in Illustrator for instance, 12 rectangles of 25 % opacity are required to add up back to the full color. I’d appreciate any explanation and/or pointers.)

frankrolf avatar Oct 04 '18 05:10 frankrolf

If I understand correctly, alpha blending works more like this:

sourceColor = 0
foregroundColor = 1

steps = 4
alpha = 0.25

for i in range(steps):
    sourceColor = alpha * foregroundColor + (1 - alpha) * sourceColor
    print(sourceColor)

Resulting in these values:

0.25
0.4375
0.578125
0.68359375

Now, when I try to use this as an overlay color to your DrawBot example, I'm not getting exactly the same tone, but it's close, and I think the principle is correct.

This is a good article: https://en.wikipedia.org/wiki/Alpha_compositing

justvanrossum avatar Oct 04 '18 06:10 justvanrossum

can this be closed?

typemytype avatar Dec 14 '18 10:12 typemytype

It can be closed, but it would be nice if the information would make it into the documentation.

frankrolf avatar Dec 14 '18 11:12 frankrolf

somehow make it comprehensive and add to the docs

typemytype avatar Dec 14 '18 11:12 typemytype

I don't think it necessarily has to be DrawBot's responsibility to explain all details about graphics rendering. We also don't explain the math behind blendMode() for example.

justvanrossum avatar Dec 14 '18 12:12 justvanrossum

@frankrolf The plusLighter blend mode does what you expect. In this blending mode any color just gets accumulated on the underlying color. This blend mode is called "Add", "Addition" or "Linear Dodge" elsewhere and is very common to use in computer graphics (result = A + B).

I'm surprised to see that I can't make this work in drawbot. Take a look at the following code. It tries to add some gray rectangle on top of another. But the color doesn't get accumulated after the second rectangle has been drawn. Where do you think it went wrong?

w, h = width(), height()
number_rects = 5
blendMode('plusLighter')
fill(0)
rect(0,0,w,h)
color = 1/number_rects
rw = w - (w/number_rects)
for i in range(number_rects-1):    
    fill(color)
    pos = (w-rw)/2
    rect(pos,pos,rw,rw)
    rw -= w/number_rects
    if round(rw) == 0:
        break

typoman avatar Apr 24 '19 11:04 typoman

I somehow don't get plusLighter to do anything noticable at all.

justvanrossum avatar Apr 24 '19 13:04 justvanrossum

It actually works like a normal blend mode right now.

typoman avatar Apr 24 '19 18:04 typoman