Adding Colours (Colors) Together like Paint (Blue + Yellow = Green, etc)

好久不见. 提交于 2019-11-30 05:11:43

问题


I'm making an iOS game using cocos2d libraries.

Lets say you have two objects that have two separate colours - defined in RGB as

Blue:    0,0,255
Yellow:  255,255,0

I want to add blue and yellow to make green.

To over complicate things, let's say that the Blue object is bigger than the Yellow object (for the sake of argument let's say that the ratio is 2:1), I'm adding twice as much blue as yellow - how to I calculate this new (light green) colour correctly.

I understand LAB * Color Space is useful for this sort of 'natural colour' kind of thing, but I'm not sure how to use it - especially in the context of a cocos2d object which (AFAIK) is limited to using RGB in its colour schemes.

I'd really appreciate practical help on how to implement this. Thanks heaps!

21/4 Update: So in LAB* blue+yellow ≠ green (which makes sense when you see they're at opposite ends of the same channel). It's actually quite a tricky problem with a little bit of discussion on SO. It seems that the ultimate answer is to use the Kubelka-Munk method that a piece of open source software called Krita uses. I can't find that anywhere (either the formula or the code itself).

This question has a link which uses HSL to work in a similar method to paint. I'm going to try to see if it works, and I'll feed back the result here.

In the meantime if anyone knows how to implement Kubelka-Munk or where I can find code to do this, or another solution, I would be very, very stoked!


回答1:


There is no color model where mixing blue and yellow makes green. Try it yourself with gouache, the only way it works is cyan and yellow. This is why you should try switching from RGB to CMYK, and back if you need. Here is how it's done

void toCMYK(float red, float green, float blue, float* cmyk)
{
  float k = MIN(255-red,MIN(255-green,255-blue));
  float c = 255*(255-red-k)/(255-k); 
  float m = 255*(255-green-k)/(255-k); 
  float y = 255*(255-blue-k)/(255-k); 

  cmyk[0] = c;
  cmyk[1] = m;
  cmyk[2] = y;
  cmyk[3] = k;
}

void toRGB(float c, float m, float y, float k, float *rgb)
{
  rgb[0] = -((c * (255-k)) / 255 + k - 255);
  rgb[1] = -((m * (255-k)) / 255 + k - 255);
  rgb[2] = -((y * (255-k)) / 255 + k - 255);
}

And then in your code, mix the cyan and yellow

float cmyk1[4];
toCMYK(255, 255, 0, cmyk1);  // yellow

float cmyk2[4];
toCMYK(0, 255, 255, cmyk2);  // cyan

// Mixing colors is as simple as adding
float cmykMix[] = { cmyk1[0] + cmyk2[0], cmyk1[1] + cmyk2[1], cmyk1[2] + cmyk2[2], cmyk1[3] + cmyk2[3] };

float rgb[3];
toRGB(cmykMix[0], cmykMix[1], cmykMix[2], cmykMix[3], rgb);  

NSLog(@"RGB mix = (%f, %f, %f)", rgb[0], rgb[1], rgb[2]);

Running the code will yield: RGB mix = (0.000000, 255.000000, 0.000000)




回答2:


Check the formulas on this site: http://www.easyrgb.com/index.php?X=MATH I've been doing similar thing, and it can be achieved by converting RGB->XYZ->Lab. However the computation is quite expensive(if you doing it for a lot of pixels).

And forget about RGB math when trying to mix colors if you want to obtain results similar to human eye




回答3:


I think, it is worth to try HSL color space. When adding colors we interpolate their Hue values (even taking in account objects weights). If the colors are 100% saturated, Luminance and Saturation values will be equal.




回答4:


Dyes don't work in the real world quite like subtractive-color models suggests. The dyes used for CYMK printing are pretty close, since they're formulated for that purpose, but many dyes made from naturally-occurring substances can behave somewhat oddly. The difficulty is that while white light is perceived as a combination of red, green, and blue, it actually consists of many different wavelengths--literally "all the colors of the rainbow"--each of which will stimulate the red, green, and blue receptors in the eye by different amounts. It is possible for two colors which appear identical to in fact contain different combinations of wavelengths; likewise, two dyes may appear identical when viewed in white light, but absorb different combinations of wavelengths. Such dyes may look identical to each other when used alone, but may yield very different-seeming results when combined with something else.

Although dyes can sometimes be tricky, however, paints are even worse. Paints contain reflective particles, and some of the light which hits a painted surface will be reflected back off the surface by the first particle it hits; in that regard, they mix like additive colors. For example, if the paint contains 20% green particles, then a significant amount of green light will be reflected, regardless of what other colors it might contain. On the other hand, some of the light which hits a painted surface will bounce around and hit multiple particles. If any of those particles absorbs a photon of some color, that photon won't be reflected. In that regard, paints behave more like subtractive colors. In practice, paints behave somewhat like additive colors, somewhat like subtractive colors, and sometimes like something weird and wacky and totally unlike either.




回答5:


Actually it seems that converting RGB->XYZ->LAB does exatly the same thing as RGB->LAB



来源:https://stackoverflow.com/questions/10139833/adding-colours-colors-together-like-paint-blue-yellow-green-etc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!