I'm looking for an algorithm to do additive color mixing for RGB values.
Is it as simple as adding the RGB values together to a max of 256?
(r1, g1, b1) + (r2, g2, b2) =
(min(r1+r2, 256), min(g1+g2, 256), min(b1+b2, 256))
I'm looking for an algorithm to do additive color mixing for RGB values.
Is it as simple as adding the RGB values together to a max of 256?
(r1, g1, b1) + (r2, g2, b2) =
(min(r1+r2, 256), min(g1+g2, 256), min(b1+b2, 256))
Yes, it is as simple as that. Another option is to find the average (for creating gradients).
It really just depends on the effect you want to achieve.
However, when Alpha gets added, it gets complicated. There are a number of different methods to blend using an alpha.
An example of simple alpha blending: http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
It depends on what you want, and it can help to see what the results are of different methods.
If you want
Red + Black = Red Red + Green = Yellow Red + Green + Blue = White Red + White = White Black + White = White
then adding with a max works (e.g. min(r1 + r2, 255)
) This is more like the light model you've referred to.
If you want
Red + Black = Dark Red Red + Green = Dark Yellow Red + Green + Blue = Dark Gray Red + White = Pink Black + White = Gray
then you'll need to average the values (e.g. (r1 + r2) / 2
) This works better for lightening/darkening colors and creating gradients.
More "natural" would be:
((r1+r2)/2, (g1+g2)/2, (b1+b2)/2)
Or more generally, x of color1 and 1-x of color2 (eg. ¾ of first color, ¼ of second):
(r1*x+r2*(1-x), g1*x+g2*(1-x), b1*x+b2*(1-x))
Few points:
This will give:
(r1, g1, b1) + (r2, g2, b2) = (min(r1+r2, 255), min(g1+g2, 255), min(b1+b2, 255))
However, The "natural" way of mixing colors is to use the average, and then you don't need the min:
(r1, g1, b1) + (r2, g2, b2) = ((r1+r2)/2, (g1+g2)/2, (b1+b2)/2)
To blend using alpha channels, you can use these formulas:
ax = 1 - (1 - a) * (1 - A)
rx = r * a / ax + R * A * (1 - a) / ax
gx = g * a / ax + G * A * (1 - a) / ax
bx = b * a / ax + B * A * (1 - a) / ax
(r,g,b,a)
is the paint color. (R,G,B,A)
is the background. (rx,gx,bx,ax)
is the resulting color.
NOTE: All variables used here are in the range [0.0, 1.0]. You have to divide or multiply by 255 if you want to use values in the range [0, 255].
For example, 50% red on top of 50% green:
(R, G, B, A) = (0.00, 1.00, 0.00, 0.50) # background, 50% green
(r, g, b, a) = (1.00, 0.00, 0.00, 0.50) # paint, 50% red
ax = 1 - (1 - a) * (1 - A) = 0.75
rx = r * a / ax + R * A * (1 - a) / ax = 0.67
gx = g * a / ax + G * A * (1 - a) / ax = 0.33
bx = b * a / ax + B * A * (1 - a) / ax = 0.00
Resulting color is: (0.67, 0.33, 0.00, 0.75)
, or 75% brown (or dark orange).