Color Choosing Paradox, also Warmer vs Cooler


I do not think I can afford an opinion on your skills, which are great.:slight_smile:

Regarding, LCH (or Lab) which are the same thing if not a coordinate and LCH easier to use, your approach seems interesting to me.

It should not be forgotten either, that CIELAB space is far from perfect. While it is excellent for measuring color differences, it is imperfect when you vary the chroma in certain colors, for example the reds become orange, the blues become purple, and so on.
One can find a solution approach here.

In the case of Rawtherapee, I implemented an automatic correction of these problems when the user check the box: “Avoid color shift”

  • First, the algorithm uses relative colorimetry, when the colors are out of gamut, mainly by reducing C (hroma) and in some cases by adjusting L.
  • Second, about 150 LUTs are used to apply a “Munsell” correction in colors where Lab is failing (orange to red, etc.).



I have been aware of this color shift problem for ages but have only recently started asking questions. If I were to use apps other than RT, e.g., GIMP or G’MIC, what would be the simplest way to accommodate for it? Do I use UPLab? If so, how?

Well, they should be! That blue color for the jeans really surprised me when it turned out to be “not blue”. Also, as far as I know “the dress” has no practical application in the digital darkroom, whereas your painting and the method you used to pick the specific colors has a whole lot of practical applications. And it’s a nice portrait (the dress, meh).

I was looking at a reference photograph that I took for the purpose of color-picking sky colors. Here’s a reduced size version with a small amount of saturation added.


You know how sometimes the sky looks yellow at the horizon? I asked my husband what color the sky was along the horizon in the photograph, and he said "cream . . . yellow . . . very warm yellow . . . - which kinda surprised me because I thought I was kidding myself that it looked yellow.

Upon eye-droppering the horizon color, it’s actually LCH Hue 208-240, depending on how close to the horizon and whether you eye-dropper to the right or left of the telephone pole. This “effect” isn’t nearly as strong as with the blue in the jeans in your portrait, and maybe most people wouldn’t even think the sky at the horizon looks yellow, but perhaps it’s from related “colors pushing each other in opposite directions” reasons.

Here is a question: if your portrait is printed and put on a blue wall next to a north-facing window, or a yellow wall next to a south-facing window, how would the surroundings affect the perceived color of the jeans?

Hmm, my skills aren’t so great :slight_smile: and my grasp of color theory - which is always and only centered on “what happens in the digital darkroom” - quickly gets very sketchy as soon as I step outside plain old RGB color mixing and ICC profile color management. Color appearance models? Spectral rendering? Unless/until I take the time to do a lot of experimenting, and figure out how to set up the equations in a spreadsheet, all the theory in the world goes right past me.

Speaking of Lindbloom’s UPLab profile, is the copyright (“Permitted Uses”) suitable for use in free/libre software? Does RT use the actual profile? It sounds like RT implements the functionality directly, rather than by using the actual profile? Is the “avoid color shift” algorithm computationally expensive?

When dealing with CIECAM02, in the narrow case of “in the digital darkroom, where the user presumably is adapted to monitor white”, is “Brightness” equal to “Lightness”? Do the equations simplify to the point where a JCH color wheel and color picker could be used in place of LCH, in terms of the computational costs?

Yes, the reason that I never considered UPLab is its Permitted Uses. The second part seems to imply that I might need to mention it even though it isn’t embedded but still a part of the processing; I have no idea. And yes, I am interested in how JCH could be implemented or at least applied simply. However, such a discussion is more suitable for my More on LCH and JCH thread.

I think we have the same meaning. When I say “spectral” I just mean a whole bunch of colorants (CIE xy coordinates). If I pick a “real world” blue paint, ignoring a lot of other factors I think I’m really just picking a whole bunch of colorants at various intensities (xyYs). In RGB I just have my three colorants at specific xy coordinates. I’m starting to think RGB exists as just three colorants for no other reason than because it was (barely) good enough and saved on bandwidth and cpu, etc.

Doesn’t that only apply for non-color managed applications? That is, HS"X" Hue 0 means the same exact perceived Red in sRGB as it does in any other color space. Without CM we’re totally lost no matter what :slight_smile:

This is pretty neat. I wonder if the same could be achieved by always using the humongous ACES colorspace. As long as you always convert everything to ACES, your HS"X" values would always be on the same scale, no? The problem would be you’d always be using a tiny portion of your interface, but “10% chroma” would have an unchanging meaning. I do find it a bit odd to use color selectors that show you such a huge gamut though. In my example earlier with my tiny slice of pie, I really wanted a way to “zoom in” on that pie slice to make it easier to use. I’m playing around with the GIMP LCH gui, is there a way to just “chop off” or zoom in, or somehow limit the scale to your selected colorspace?

Very true, but I think each “flavor” is trying to serve a different purpose. The way LCH and HCY (tries to ) keep luma constant seems pretty useful, but maybe HSL or HSV is more useful for some other purpose.

I still don’t really see the problem, as long as you exchange the color space information along with the HSV numbers. When you say “5,20,100” it doesn’t mean anything, even with LCH, unless you also say “those numbers are LCH numbers” :slight_smile: Having the values scale with your current color space (likely your display) is probably pretty useful, honestly. You would know 50% is right in the middle of what you can work with, and leave some headroom and bottom end. An absolute number is also useful, but I’m starting to think having 3 or 4 color dialogs open at once might be best, maybe HCY, RGB, and LCH.

Interesting! Thanks for using my image, actually, feel free to use the actual picture if you’d like. Full size is over here:

I think it’d be cool if we could take that limited gamut shape, whatever it may be, and map that to a new color wheel. Makes sense right? The RGB triangle is mapped to a wheel, why not any arbitrary colorants?

That is funny. It’s hard to know what’s real, what’s in the mind, or what is an effect from the camera, etc. So frustrating. I recall trying to study the gradient in the sky just after the sun set. So I knew the sky would get darker as I looked higher and higher, but what I didn’t expect was that for every few degrees I tilted my head back, my vision “reset” and re-calibrated to the new gradient. So, it barely seemed to get any darker!

I think as long as you included the background in the painting, the effect would remain more or less on the blue wall, but if you cut the figure out of the painting I’m sure that would destroy the effect. The yellow wall… I think that would enhance the effect, maybe. Another fun thing to try would be to create a synthetic ICC profile using the gamut mask or the plot you generated, and set the white point to the center of that triangle. Then load it in gimp w/ that profile assigned and see what happens when you convert it to sRGB. I really have no idea. It’d be interested to adjust saturation, etc, and then convert back to the synthetic profile. I have no idea if that is even a coherent thought :slight_smile:


For correction Munsell<==>Lab, I don’t use UPlab Profile (I think it’s buggy, but thats not the problem…). I use 195 LUT (I deposited a copyright) for each Munsell reference : Color ,saturation and Luminance (in Munsell notation). I give to the LUT, Luminance Lab, Chroma Lab, and Hue Lab, then I obtain a correction. This system is not perfect (what is perfect ?), but differences are very, very tiny (1 or 2%). The system is very fast, and don’t use much memory (each LUT is very small about 140 values)

For Ciecam, I don’t simplify calculation (before we work together, I just simplify GUI), JCH is different from LCH, Brighness is different from Lightness, etc. But it is difficult to implement JCH elsewhere without using all the equations

When I read this bit about unsaturated color zones I really started to feel like the color wheel is just plain imperfect and we have to live with that. If brown is a unique color and not just an unsaturated (edit; or darker) orange, shouldn’t it exist as a 100% saturated color on the outer edge of the wheel (as its own hue angle)?

In RGB color mixing in the digital darkroom, colors are made using R,G,B channel values from well-behaved RGB matrix color spaces, that might or might not also be ICC profile color spaces, depending on whether the editing program uses ICC profile color management.

There are four, really only two, basic editing operations that can be performed on RGB channel values: add/subtract and multiply/divide (there’s also raising to a power as per “gamma curves”, but let’s put that to one side). Shine two different colors of light onto the same white surface, that’s addition. Put a filter over a light to modify the color, that’s multiplication. That we can multiply RGB channel values doesn’t make RGB any less an “additive” color space than when we add RGB channel values.

Unlike mixing colors from lights, real world paints applied to real world surfaces don’t mix additively. They mix subtractively, but this isn’t the same “subtraction” that is involved in RGB color mixing (in RGB color mixing add/subtract are just inverse operations).

“Subtractive” when referring to mixing surface colors (such as actual paints applied to canvases) is more like “intersection” of the wavelengths (and percentages of reflection for each wavelength) that the first paint color reflects and the wavelengths (and percentages) that the second paint color reflects, complicated by any chemical interactions and surface properties that get changed with mixing the two paints, and etc, with the “etc” covering a lot of territory.

First consider the chemistry and physics of mixing paints of various colors to make new colors that are then applied to a canvas (and of course the canvas itself influences the resulting color unless the paint is fully opaque).

Then consider using spectral rendering to reproduce in the digital darkroom colors that have the same mix of wavelengths as the paint colors on the canvas (the mix of wavelengths reflected from the paint on the canvas to our eyes, that we perceive as colors). These are fairly separate things, yes? Not that I have any clue at all about what spectral rendering actually involves!

The thought processes involved in choosing and mixing colors seems to me to be “very much in common” whether the medium is digital or wet. But the specific “mixing to make new colors” considerations change radically.

Indeed, but at the very least, we can do the pure wavelength math and get a very good result! The goal is not necessarily to mimic every nuance of paints, but just have “more lights”. We can mix these extra lights basically the same as we are mixing RGB.

Not as separate as it might seem! :slight_smile: I hope you can try the Burns libmypaint branch. Just remember that rgb.txt file has to be in your current working directory, and it will take a while to load the first time you use a brush with Subtractive mode enabled, so MyPaint will appear to be hung for several minutes (hey, I never said I could program!)

My apologies for skipping around, this is a very thought-provoking thread! and I’m trying to catch up on a lot of topics touched on along the way.

Anyway, perhaps the following is relevant to the goal of moving colors towards warmer and cooler versions of themselves. I use Multiply blend mode (and sometimes Divide) to make colors warmer or cooler, using the range of “natural light” warm and cool hues given by MacEvoy, except that he gives JCH hues, and I’m using LCH hues.

Multiply in RGB mimics putting a color filter in front of a light source out there in the real world. In the real world, the resulting colors in the scene depend on the original scene colors, the original light source color, and the filter color.

In spectral rendering, my understanding (thin as it is) is that it’s possible to get RGB colors to mix like “real world lights and colors and filters” mix.

In an RGB matrix color space, the resulting color from multiplying two other colors together depends on the RGB color space primaries. Here is an example:


Notice the image on the left, in the linear gamma Rec.2020 color space, has warmer, nicer looking skin tones. The difference is subtle because the colors are subdued - images with more vibrant colors would show greater differences. As an aside, I had default GIMP and also my modified GIMP-CCE both open, but that’s not what makes the difference. Each version of GIMP produces correct LCH blend mode results, and also the exact same LCH blend mode results.

For the sample “make the colors cooler” screenshot above, and given the way I set up the layer blend modes, the only difference that makes a difference is the two color spaces - linear Rec.2020 in GIMP-CCE and linear blending in sRGB in default GIMP. And the only layers that make a difference are the Multiply layers for making the colors cooler or warmer. It’s worth experimenting to convince yourself this is true. So here is a zip file with two small XCF files, set up to use as shown in the screenshot above: (208.3 KB)

One XCF file is for GIMP-CCE, and the other is for default GIMP - the two versions of GIMP don’t produce compatible layer blend modes.

  • In default GIMP it’s best to stick with the built-in sRGB color space, though since some new “anyrgb” code has been added to babl, in default GIMP the LCH blend modes and also Multiply seem to produce correct editing results - this is really cool! a definite step towards “anyrgb” for default GIMP! Make sure to choose linear precision, 32-bit floating point.

  • In CCE, it’s necessary to use linear gamma RGB color spaces, such as any of my github ICC profiles that end in -g10.icc.

To see the difference the RGB color space makes:

  • Duplicate the original layer stack and convert the duplicated layer stack to the desired color space (don’t assign a new color space, but rather use “Image/Color Management/Convert . . .”

  • Resize the layer stack to the size of whatever sample image you have that you’d like to experiment with making colors warmer and cooler. There are “sample colors” layers already, that can be replaced.

  • In the layer stack there are three “make the image cooler” layers and three “make the image warmer” layers. But dividing by a cool color makes the image warmer, and dividing by a warm color makes the image cooler. If anyone wants to experiment with Divide.

  • Try changing the top “Lightness” layer to Luminance. Using Lightness vs Luminance affects the resulting color saturation.

Elsewhere on I posted a link to a study by Mansencal that suggests that Rec.2020 produces Multiply results that are much closer to “spectral” than Multiply results in sRGB. I’d suggest also trying ACES, ACEScg, ProPhoto (“LargeRGB” in my github profiles), and AdobeRGB (“ClayRGB” in my github profiles).

1 Like

It’s on my “to do” list. I’ve never used MyPaint because it’s not color-managed, but I’m very curious about that Burns branch.

1 Like

Continuing on with the topic of making a single color or a whole image warmer or cooler in some sort of perceptually meaningful way, and assuming one is interested in the kinds of “warmer” and “cooler” associated with natural light sources, then an already described option is to multiply the original color or image by a given warm or cool color chosen using MacEvoy’s range of warm and cool JCH Hues, or LCH approximations thereof, and doing this in a given RGB matrix color space.

Another option is to use Ciecam02 to chromatically adapt the color or the image from the presumed starting temperature to the desired number of degrees Kelvin warmer or cooler. RawTherapee has this ability thanks to @jdc’s wonderful Ciecam02 module, for which he very kindly expanded the user interface to allow users to do the sort of thing I just described.

So for easy comparison, here’s @briend’s original portrait, somewhat downscaled:


Here’s the pp3 file with the RawTherapee settings for making the color temp 1500K cooler (more blue), and hopefully @jdc will let me know if the settings even make sense (I think they do, but it doesn’t hurt to ask someone who knows what they are doing):
1ca5b34894e2ec875d8e5e50d2942036599807e8-16i.tif.pp3 (10.1 KB)

Here’s the resulting portrait with cooler colors:


As an experiment, to see if I could duplicate the Ciecam02 output using default GIMP 2-9 and the built-in sRGB color space, I set up the original portrait layer, the “Multiply” layer, and the original portrait layer again but set to LCH Lightness blend, and then used the Hue-Chroma tool to modify the color of the Multiply layer until the resulting cooler image matched the Ciecam02 image as closely as possible.

To my surprise the color LCH (101.1, 17.0, 271.0) set to Multiply blend produced almost an exact match to the Ciecam02 output, both visually and based on using the Difference blend mode to compare the two images. The results are too close to justify even uploading the “Multiply” output, but of course if you want to check for yourself it’s very easy to set the layer stack up in GIMP - just use the same arrangement as I described earlier - it does require using floating point precision in order to actually dial in the right LCH color.

The resulting image is actually very close to the Ciecam02 output even when the Lightness layer is made invisible. It never would have occurred to me to use a color with a Lightness >100 to keep Multiply blend mode from make the image darker. Now if only we knew ahead of time what LCH color set to Multiply blend would more or less produce something reasonably close to Ciecam02 output, and of course @briend’s portrait has fairly unsaturated colors in a narrow range of hues, so it would be interesting to experiment with other colors.

1 Like

This makes it sound so simple :-). So, I suppose you still need to know if your light source is warm or cool, for starters. Ideally you would know precisely what color your illuminant is, no? Then, you’d know exactly which color hue to multiply your color with. For warmer, you’d multiply your color with the same color as your illuminant, and for cooler the opposing color (+180 on the LCH wheel?).

So, in your example you’ve shifted the colors definitely cooler, but now some hues are definitely a (slightly) saturated “blue” hue. Those are outside the gamut I was originally painting in, no? I was thinking (and maybe this is wrong) that we should still be confined to whatever gamut colorants we’ve chosen from the start of our painting.

Maybe a more extreme example would work better for my brain. Like, an image entirely composed of red apples and other red objects (LCH hue ~0), illuminated by a very bright red lamp. Would we multiply our shadow colors by LCH hue 180? I think so, but wouldn’t we want to avoid multiplying them so much that they actually become saturated LCH 180? I think the answer to that depends on your gamut mask. If not using a mask (and using the implied mask of your whole RGB colorspace) then I think yes, you’d end up with LCH hue 180. But for a mask that is entirely, say, limited to fairly saturated hues 330-60, I am thinking maybe not.

Going back to your example here, when you multiplied my painting by the blue, didn’t you effectively shift the colorants, and thus shift the white point? (where was the white point in my original painting, anyways? The center of the triangle shape?) I’m searching for the right terminology here. . . but I think keeping the white point static and still having a way to make colors warmer/cooler is still confusing. I took a sample of the original shirt sleeve as the “whitepoint” and it is LCH hue 67 or so, but when shifted cooler it is now LCH 290.

Maybe it really is a matter of just multiplying the brush color by your (illuminant+180) but keeping an eye on your position within your “mask” and just stop when you approach your gamut borders. Edit- but this doesn’t really help shifting an entire image, does it? I wonder if that synthetic ICC profile would come into play, after all. . .


I will not pass judgment on the photo and its rendering, but only on the use of Ciecam.

Admittedly, this use is not what is expected “normally”, but it must be recognized that this use provides a significant improvement to the images by giving the ability to change the color balance with a CAT02 adaptation.

Thank you for this improvement

Hi @jdc and my apologies! I learned a long time ago that what I try to say is not always what other people hear. I suspect I similarly misunderstand other people . . . But in case I did understand what you meant to say, I wasn’t asking for an aesthetic judgment, but only whether the attached pp3 file shows the right parameters in the Ciecam module to effect a chromatic adaptation from 5000K to 6500K, not as a way to compensate for specific output display viewing conditions that differ from the editing viewing conditions, but rather to make the image cooler under the same editing viewing conditions.

I think I managed to get all the parameters correctly dialed in - the new interface is very easy to navigate. I did use “100% adaptation” instead of the precalculated “85% adaptation”.

I’m very curious about the precalculated adaptation percentage values - is there an easy to understand explanation of how these percentages are calculated? Does it have to do with the direction? amount? starting point? of the requested temperature change? Does moving the green-magenta slider affect the resulting percentage? I think you mentioned elsewhere that we don’t completely adapt to all possible “colors of the light”, but I was surprised at the 85% figure for a change from 5000K to 6500K.

The “very bright red lamp” that @briend mentioned would seem to be an extreme case where chromatic adaptation of the viewer to the lighting would be very incomplete (near or at 0%), as all colors would be reduced to red colors if the lamp is the only light source. Also, I’m guessing, and could be completely 100% wrong, that Ciecam02 deals with natural full spectrum light sources, and a red lamp (such as a wet darkroom light for wrking with film that’s insensitive to red light) by definition isn’t a full-spectrum light source.

Speaking of aesthetic judgments, I agree with you 100% that using Ciecam to modify the white balance of an image does produce very pleasing results. I’m curious to see results of using the Ciecam module to try to fix the white balance of camera-saved jpegs shot using the wrong white balance, and very curious to see what would happen when using Ciecam to modify the colors in Monet’s haystack paintings: Haystacks (Monet series) - Wikipedia - hopefully I’ll find the time to do some experimenting in the near future - if anyone else tries using the Ciecam module for either of these kinds of images, please share your results!

Unrelated to the current topic, to anyone who wants to modify shadow tonality and/or saturation/colorfulness/etc, try using the RT Ciecam02 module - you might like results quite a lot.


Ciecam and cat02 comes from many works more or less empirical.

In the case of the calculation of “Cat02 adaptation”, the only 2 parameters taken into account are:

  1. Surround (which itself depends on 3 coefficients f, c, nc) : f can take the values 1 or 0.9 or 0.8 for average, dim, dark
  2. “Scene absolute luminance: La” between 0.01 and 16384

And then calculate as “d_factorfloat”

float Ciecam02::d_factorfloat ( float f, float la )
return f * (1.0f - ((1.0f / 3.6f) * xexpf ((-la - 42.0f) / 92.0f)));


And to go further, it would be “necessary” that I integrate a part of Ciecam (only that concerning CAT02) to “locallab” and thus be able to make local corrections touching the white balance with chromatic adaptation

As a possibly relevant aside, Gurney’s mask in the example masked portion of his color wheel includes achromatic colors from the center of a paint wheel that includes hues from around the entire spectrum, and the mask also includes low-chroma colors from the other side of the neutral center. Your more restricted hue range only has achromatic colors that result from lowering the chroma to zero - I’m speaking now of actually achromatic colors in the color gamut, as viewed in isolation from each other.

Your portrait shows a very clear - downright startling clear :slight_smile: - example of simultaneous hue contrast - the surrounding warm colors push the low-chroma colors in the jeans to look blue, when really the jeans aren’t blue at all but instead are painted using the same hues as the rest of the image, but using very low chromas. I used the hue-chroma tool in GIMP to verify that the “illusion” persists even when the colors are rotated, though with varying degrees of strength, though this also seems to depend on other colors and light sources on the monitor screen and surrounding the monitor.

The exact same color palette in a different painting won’t necessarily show any such “blue where blue isn’t”. Take a look at Kenyon Cox’s Portrait of Augustus Saint-Gaudens ( - similar color palette to your portrait, but there is not a speck of “apparently blue” anywhere to be seen, though my eyes insist on seeing his necktie as green (it’s not, but this probably isn’t a case of simultaneous hue contrast but rather of the fact that as yellow hues get darker we perceive the color as increasingly green - several comments back you gave the link to the relevant handprint page):

“Simultaneous color contrast” is a well-known phenomenon - colors viewed in combination making each other look different than the same colors viewed in isolation (which is where you started this thread :slight_smile: ). But the actual effect depends not on only on the colors in the palette, but also on where on the canvas/screen the colors are in relationship to one another. Color palette alone is not enough. Tonal contrast isn’t enough. Chroma contrast isn’t enough. Setting up that lovely “jeans look blue” also required the right spatial arrangement of the colors.

Here are some reference pages - they don’t make for easy reading:

Also see Chapter 5 “The Instability of Colors” (great chapter title!). Many of the illustrations are not so convincing, at least not to me. But for some of the slides the “color instability” is very apparent - I actually had to color pick the background neutral color for Slide 56 to convince myself the two backgrounds (one with a green figure and one with a magenta figure) were actually the same color backgrounds.

Similar effects of “one color influencing how we perceive another color” are easy to create using “same color against a lighter and darker backgrounds” and “same color against more and less saturated backgrounds”. The case of “hues driving each other towards their complement” is easier to demonstrate with sequentially viewed colors. Just stare at more or less saturated blue on your monitor screen for a few seconds, then look at white, or even very low-saturation blue - you’ll see orange or yellow depending on the particular blue you just were staring at. But MacEvoy seems to be saying it’s not so easy to produce the same “push towards the complementary hue” with colors placed side by side.

So it seems to me that what you’ve accomplished with your portrait is an extraordinarily clear case of surrounding colors pushing the perceived hues of neutral or low-chroma colors - even with the same hue range as the surrounding colors - towards the complement of the surrounding colors.

I’m not sure whether or how the idea of establishing a new white point or a “subjective neutral” using a color palette might make sense as a way to explain this phenonmenon of colors influencing each other, especially as this explanation would seem to only apply to hue shifts that aren’t even always apparent, even in images with the same color palette.

1 Like

Hi @briend - and thank you! for letting me use your painting. I was very hesitant to ask you about using your painting as I know you are not fond of overly saturated colors (neither am I), and I didn’t want to put you on the spot. But as you volunteered :slight_smile: and given that your painting very dramatically shows the difference between the two ways to use LCH to add saturation to an image, I did add your painting to the tutorial. I also added a note saying that adding massive amounts of saturation to your painting amounted to something like the artistic equivalent of negligent homicide.

1 Like