# Photoshop-style color replacement ...using material nodes?

Okay, it's a bit of a crazy idea but... I have a sort of complex material where just certain bits have this hot magenta (no, it's not a missing texture) that needs to be toned down or maybe even replaced with another color entirely.

Sure, I could do it in Photoshop, but would rather address the issue within the material. Especially since materials that emit or transmit can get their colors on other objects in the scene, and also because for animations one would want to avoid the need for post-processing each frame in an image editor. (Also I like to go pure Blender whenever possible.)

So this now has me wondering (although it seems unlikely) - is there some kind of node setup that could target a specific color before it reaches the shader node and replace it with some other color? Perhaps also a way to adjust how specific or broad it is in capturing that color?

Kind of like what is possible with Select > Color Range... in Photoshop, for those who are familiar with that feature.

I'm thinking that with some clever combination of MixRGB, ColorRamp, and Hue/Saturation/Value, it might be possible. But I'm out of ideas beyond that. :-)

## Update

User Robin Betts has previously posted an answer that nearly solves my problem!

(Okay, it's not really a problem since I can fix my image in Photoshop, but it addresses the challenge.)

With some tweaking, I've prepared two node groups that are very similar to the one in that answer. Here they are in a .blend:

One replaces a color - not with a solid color fill, but instead using the "Color" blend mode in the MixRGB node. This one small adjustment made the result much more desirable for me, as variance in value is now preserved.

The other node group targets a color in the same way, but then shifts the hue in areas that have that targeted color. A different approach for doing something similar.

Each method has its merits, but just when I thought I had exactly the node groups I needed, I tested them on my original image and found that they don't work on high dynamic ranges of color. It appears the values climb out of reach and cannot be targeted.

I tried "normalizing" the RGB channels, which improved the result, but not completely nor predictably.

So now the question has become: How to replace a color even when its dynamic range is high?

• Possible duplicate? Maybe this node group will do the job Aug 17 at 13:30
• @RobinBetts Thank you!!! Your answer is extremely close to what I need, and I think I see how to fine tune it to be exactly what I need. I might post details later. Aug 17 at 14:22
• If you need a tweak, I'll answer here. Aug 17 at 14:23
• Do you mean HDR -> HDR? Aug 19 at 16:56
• @RobinBetts Yes. Turning down the Film Exposure in Cycles is a quick way to test for it. In the .blend I posted above, the material all emits at a value of 1.0, so everything works fine. But when used on a material with some much higher values, those colors escape the reach of the color targeting... if that wording makes sense. Aug 19 at 17:02

What I've worked out to preserve high dynamic range, that is getting good-looking results (not sure if 100% accurate, but looking satisfying to me)... is to do the following:

1. Separate HSV
2. Normalize the Value channel using a ColorRamp (or Map Range) node
3. Combine HSV
4. Run that result through the color replacement process
5. Separate HSV again
6. Combine HSV again using the original color Value

It looks like this:

I plan to clean up and put those nodes coming before and after the color processing into the group as well. Although I think seeing it this way makes it easier to understand.

Note the extremely low value on the group node's Influence slider, due to the extreme brightness of the magenta in my crazy material. ;-) Raising it much higher than this causes all colors to be replaced with the new color, in my case.

• If this is working for you... Great! As far as I can see, that's clamping the value, rather than normalising it? There would still be a loss of accuracy, but maybe compress -> compare -> decompress might be a way to go? That would be a Map Range -> (0->1) on all the components, but you would have to know what the source limits were? Aug 19 at 18:02