Is there an algorithm for mixing colors that works like mixing real colors?

General RGB color mixing is very different from painting color mixing, it is light blending instead of pigment blending.

For example:

Blue (0,0,255) + Yellow (255,255,0) = Grey (128,128,128) 

(It should be blue + yellow = green)

Is there any known color mixing algorithm that works like mixing real colors?




My approach

I have already tried the following:

Converting both colors to HSV and mixing colors (multiplied by a coefficient calculated from saturation) and a simple average for saturation channels and values. Then I calculated the average brightness from both colors and adjusted the resulting color according to this brightness. This worked pretty well, but mixing shades was sometimes wrong, for example. g :.

 Red (Hue 0°) + Blue (Hue 240°) = Green (Hue 120°) 

I found out that sometimes I need to shift the hue value by 360 ° (when the difference between the hues is more than 180 °).

 Red (Hue 360°) + Blue (Hue 240°) = Magenta/fuchsia (Hue 300°) 

But this bias was not very good, for example:

 Cyan (Hue 179°) + Red (Hue 0°) = Hue 89.5° Cyan (Hue 181°) + Red (Hue 0°) --> shifting is performed (the difference is greater than 180°) Cyan (Hue 181°) + Red (Hue 360°) = Hue 270.5° 

(Hue 179 + Red) and (Hue 181 + Red) leads to two completely different colors.




Then I tried the CIE Lab color space (as in Photoshop), which is designed to be closer to how people perceive colors.

I used a simple average for each corresponding two channels, but the results did not satisfy, for example, I got pink (64, 26, -9.5) from blue (98, -16, 93) and yellow (30, 68, -112) . These coefficients were taken from Photoshop.

Perhaps if I used some other operation than the average, it could work, but I do not know what.




CMYK does not work either , the results are similar to RGB or LAB.




Neither trivial incremental nor subtractive color mixing in any of these color spaces seems to produce natural results.




Working implementations

Krita - Paint Mixer

Raster graphics editor At some point, Krita implemented a more realistic color rendering: http://commit-digest.org/issues/2007-08-12/ (plug-in for a smooth mixer)

They say that this is the first public application that implements a special technology using the Kubelka and Munk equations describing the behavior of pigments.

Here's a Krita color mixing video: https://www.youtube.com/watch?v=lyLPZDVdQiQ

FiftyThree Paper

There's also an article on color mixing in the Paper for iOS app developed by FiftyThree . They describe how they innovate and experiment in the area, and also offer patterns of mixing blue and yellow, which leads to green. However, the actual process or algorithm is not described here.

Citation:

“In search of a good blending algorithm, we first tried to interpolate different color spaces: RGB, HSV and HSL, then CieLAB and CieLUV. The results were disappointing,” Chen said. “We know that red and yellow must be orange or red and blue must be purple, but there is no way to achieve these colors no matter what color space you use. There’s a technical axiom: do the simplest thing that might work. Well, now we tried the simplest approaches, and they didn’t even feel remotely. "

It seems that just like Crete, Paper implements the Kubelka-Munk model:

[...] the Kubelka-Munk model had at least six values ​​for each color, including reflection and absorption values ​​for each of the RGB colors. “While the appearance of color on the screen can be described in three dimensions, color mixing occurs in fact in six-dimensional space,” explains Georg Peternigg, co-founder and CEO of FiftyThree. The Kubelka-Munk document allowed the team to translate the aesthetic problem into a mathematical foundation. [...]

From all this information, it seems that an implementation based on the Kubelka-Munk model can be a way to move forward and offer results that are much closer to reality.

Despite the fact that this looks like a complicated process, I have not yet seen much good information on how to implement something like this.




Related Questions

These questions were published after everything was connected with the same.

None of them have an answer.

  • Mixed color calculation in RGB
  • A color search algorithm between two others - in the color space of painted colors
  • Introducing Kubelka-Munk as Krita to mix colors like paint



Other related links and resources

+49
language-agnostic algorithm colors blending
Aug 29 '09 at 13:26
source share
7 answers

The correct answer is NO, because there is no right working model of how “color mixing in the real world” really works. It is too complex and conditional, and actually does not look like the simple red-blue-yellow material that we learned at school (in fact, this requires that all Chemistry and many physicists and biology be allowed).

However, the simplified answer is: YES, use subtractive mixing, not additive mixing.

The color mixing we studied in elementary school is based on combinations of pigments, which are a form of subtractive color mixing (very simplified). That is, the more colors we add together, the darker it becomes, because each pigment subtracts a little more light.

On the other hand, almost all computer color schemes are additive because they are based on a combination of light waves (very simplified), so they become brighter because each color adds a little more light.

The RGB + pattern is somewhat advanced in addition to the subtractive pattern that we learned in most American elementary schools (this is RBY-). However, they do not match exactly, and it can be difficult to convert (research now ...)




OK, if you just want to switch from additive combinations in RGB to subtractive, you can use the following inverse Bayesian formula to combine the two colors:

 NewColor.R = (Color1.R * Color2.R)/255 NewColor.G = (Color1.G * Color2.G)/255 NewColor.B = (Color1.B * Color2.B)/255 

Adjusting the difference at the chromatic poles (from G to Y, then back to G) is much more difficult ...




It has been pointed out that this creates a black problem for example, and technically it is correct for a true subtractive system, however, if you want more dilution / subtractive system, you can try this instead:

 NewColor.R = 255 - SQRT(((255-Color1.R)^2 + (255-Color2.R)^2)/2) NewColor.G = 255 - SQRT(((255-Color1.G)^2 + (255-Color2.G)^2)/2) NewColor.B = 255 - SQRT(((255-Color1.B)^2 + (255-Color2.B)^2)/2) 

This creates a dark gray, not black. But to get Yellow or something close, you still have to fix the problem of aligning the poles of the color scheme.

+23
Aug 29 '09 at 13:47
source share

There are two different possibilities combining colors:

So, with subtractive color mixing, the result is what you expected, but there is no blue color, instead there is blue:

Yellow + Blue = Green

In general, subtractive color mixing simply “subtracts” (filters out) the white color, while mixing the additives mixes with black. (base colors of subtractive invert from additive: red → cyan, green → magenta, blue - yellow)

So, if you start with a white screen using filters:

min (white (255 255 255), yellow (255 255.0), blue (0.255.255)) = green (0.255.0)

+5
Aug 29 '09 at 13:33
source share

There is code for realistic color mixing in krita: https://projects.kde.org/projects/calligra/repository/revisions/master/show/krita/plugins/extensions/painterlyframework .

Note that the code containing the light source file is GPLv2 +. It can convert from RGB to wavelength, perform composition and convert back.

+2
Apr 21 '12 at 6:22
source share

I think your problem with the combination of shades is that you do this by adding two corners and dividing them into two. As you noticed, the result often does not make sense. I think it would be better for you to convert the angles to Cartesian coordinates on the unit circle, averaging them and find the angle of the resulting point (ignoring the value).

+1
Dec 21 '11 at 18:40
source share

One way to make a subtractive mixture of RGB colors is to first convert the RGB colors to spectral reflection curves. The conversion is pretty simple, and once you do, you can make a true subtractive mixture of reflection curves and then convert the result back to RGB. There is one more similar question: https://stackoverflow.com/a/212716/212 where the process is discussed in more detail.

+1
Apr 30 '15 at 12:03
source share

I wonder if the inverse of the RGB value calculation works. As far as the subtraction of lights is concerned, technically the subtraction part can be calculated by simple mathematics.

For example, cyan + yellow

cyan = 0x00ffff yellow = 0xffff00

Their inversions are 0xff0000 and 0x0000ff, which means that they completely absorbed the red and blue lights. Their 1: 1 mixture should absorb half of the red and blue light (since the other half of the mixture can still reflect red and blue light), which is consistent with (0xff0000 + 0x00ffff) / 2 = 0x7f007f. Now we subtract the value from 0xffffff, we have 0x80ff80, which is green!

+1
Oct 13 '16 at 3:16
source share

Check this implementation for additive, subtractive, and other mixing algorithms.

Fully functional (called in java), so you can test all the colors you need to mix and see if it suits your needs.

As the other answers indicated, Blue + Yellow (exactly Blue + Yellow ) Green on the CMYK subtractive algorithm. See for yourself

-one
Jan 30 '13 at 4:45
source share



All Articles