-2
\$\begingroup\$

Let's say I have 4 light colors:

(0.6,0.0,0.0), (0.0,0.6,0.0), (0.1,0.1,0.1), (0.1,0.1,0.1)

And now I want to combine them properly. I can't add them together, because if I add for example 3rd color and 4th color I will receive (0.2,0.2,0.2), while I would expect it to be (0.1,0.1,0.1). So what is the way to mix colors together and receive final light color?

I tried something like this (Pseudo-code example for color 3 and 4):

color3 - color4 = (0.0,0.0,0.0)
finalColor = subtraction result (0.0,0.0,0.0) + color3

But sometimes it doesn't work.

Colors

\$\endgroup\$
  • \$\begingroup\$ What's the context? What do you want to do with these colours? \$\endgroup\$ – Alexandre Vaillancourt Feb 11 '16 at 18:37
  • 1
    \$\begingroup\$ I'm creating multiple lights in my game engine. \$\endgroup\$ – skprime Feb 11 '16 at 18:40
  • 2
    \$\begingroup\$ Why should it be (0.1,0.1,0.1)? If you shine two flashlights on the same area it will be brighter than if you shine only one flashlight, right? \$\endgroup\$ – amitp Feb 12 '16 at 0:06
3
\$\begingroup\$

Your question makes it clear what you don't want, i.e. a combination of a color like (0.1,0.1,0.1) with itself to result in pure addition, giving (0.2,0.2,0.2), when you would expect it to result to stay the same (0.1,0.1,0.1). However, you never made it clear what you want in other cases, such as when combining your first color, (0.6,0.0,0.0) with your second color (0.0,0.6,0.0). I guess that in this case you are expecting the result to be a pure plain addition, giving (0.6,0.6,0.0).

Here are the visual representations of the 4 colors you gave as example in the second line of your question:

enter image description here

So, here it is a visualization of what you get when purely adding (0.6,0.0,0.0) and (0.0,0.6,0.0), which is equal to (0.6,0.6,0.0):

enter image description here

Now, when summing two lights of the same color, like (0.1,0.1,0.1) plus (0.1,0.1,0.1), as @amitp has accuratelly pointed out in the comments, there is no reason why you should expect that two hlights overlapping would NOT result in a brighter version of that original color. Thus, this is what you got, i.e. (0.2,0.2,0.2):

enter image description here

In other words, that is perfectly correct and "realistic": two lights of different color result in a brighter light of composed color, while two lights of the same color result in a brighter light of that original color.

That only works well because of something that @Draco18s correctly pointed out in her/his answer: any values above 1 (i.e. 255) will be clamped to 1 (i.e. 255). It means, in a rough and imprecise way to put it, that when a light color is in its brightest RGB version, then of course the overlap of two such lights just cannot result in any brigther versions of themselves. Thus, summing (1,0,0) with itself still results in (1,0,0), which looks like the following:

enter image description here

So, to sum up, there is nothing wrong there that you need fixing. However, maybe what you are looking for is something that is not exaclty what one can see in the picture you posted in your question. For instance, think of the averaging of two colors instead of their addition (I mean, literally the sum of the two colors divided by 2).

The average of (0.6,0.0,0.0) and (0.0,0.6,0.0) is (0.3,0.3,0.0). Which looks like the following:

enter image description here

Now, in that case, the averaging combination of the colors results in a new color that looks similar to both the original colors. Instead of red and green resulting in yellow, now you have red and green resulting in something that looks, in a perception sense of the word, like a mix of the red and green. However, the downside is that due to the nature of the average, it also looks a bit darker than the original two colors that compose the third. Therefore, this may or may not work for your particular situation, depending on what you prefer.

But of course, in this case, averaging (0.1,0.1,0.1) with itself will now result in (0.1,0.1,0.1):

enter image description here

Whether averaging or pure addition (or any other formula) works best for you, it is you who can decide. However, within the RGB color space alone, you can't easily get the result of averaging for (0.1,0.1,0.1) plus (0.1,0.1,0.1) AND the result of pure addition between (0.6,0.0,0.0) and (0.0,0.6,0.0). Unless you just hard code if-else exceptions, passing different formulas for each types of cases. But of course, that wouldn't keep consistency, would probably look less natural or could result in pretty unpredictable results.

PS: For a fairly detailed explanation on color mixing and related discussions, see Manipulating colors in .NET - Part 1.

\$\endgroup\$
4
\$\begingroup\$

Define "properly." There are multiple ways of blending color. Additive blending works as you describe, 0.1 + 0.1 = 0.2 because we don't care if this value goes over 1 (as the values are clamped [0-1]). If you want to account for High Dynamic Range color, then you have to perform an additional step: rescaling.

HDR works by saving the largest value produced across the standard render (letting per-pixel values exceed 1), then dividing every pixel by that value, or some value close to it, so that the whitest whites stay white, the darkest black stay black, and everything else in between scales. This is how our eyes work, and why going into a dark room you can't see (until your eyes adjust) only to have the sun dazzle you when you come out again.

\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.