Having trouble implementing a function in the node editor where the source uses if/else logic

I am creating a color saturation node group in blender as an exercise. This is the code I'm trying to implement:

RGBtoHSV= function(color) {
var r,g,b,h,s,v;
r= color;
g= color;
b= color;
min = Math.min( r, g, b );
max = Math.max( r, g, b );

v = max;
delta = max - min;
if( max != 0 )
s = delta / max;        // s
else {
// r = g = b = 0        // s = 0, v is undefined
s = 0;
h = -1;
return [h, s, undefined];
}
if( r === max )
h = ( g - b ) / delta;      // between yellow & magenta
else if( g === max )
h = 2 + ( b - r ) / delta;  // between cyan & yellow
else
h = 4 + ( r - g ) / delta;  // between magenta & cyan
h *= 60;                // degrees
if( h < 0 )
h += 360;
if ( isNaN(h) )
h = 0;
return [h,s,v];
};

This is the part that I am struggling to implement:

if( r === max )
h = ( g - b ) / delta;      // between yellow & magenta
else if( g === max )
h = 2 + ( b - r ) / delta;  // between cyan & yellow
else
h = 4 + ( r - g ) / delta;  // between magenta & cyan

I am trying to figure out how to chain math comparison nodes in the right way but I am just stuck.

Here is the node group so-far (Updated): At the very end is where I am stuck. I'm not sure how to set up a three-way if/else node structure.

If r === max, else if g === max, else catch-all.

Any help would be hugely, hugely, appreciated!

Rewrite the code as

h1 =     (g - b) / delta;  // between yellow & magenta
h2 = 2 + (b - r) / delta;  // between cyan & yellow
h3 = 4 + (r - g) / delta;  // between magenta & cyan

h  = (r==max) * h1
h += (1 - (r==max)) * (g==max) * h2
h += (1 - (r==max)) * (1 - (g==max)) * h3

where (X==Y) means 1 if X and Y are equal, 0 if they're different (ie. what the "Compare" operation on a Math node does).

This is just a bunch of arithmetic operations, so it's straightforward, albeit laborious, to translate into nodes.

edit

Here's how I did it with nodes. This does

tmp = (g==max) ? h2 : h3;
h   = (r==max) ? h1 : tmp; The If Then Else node can be done with a lerp • I seriously appreciate the help. I can kind of see where you're going with this, but I don't understand how to implement the bottom half. Why are you doing += operations instead of comparisons? I realize it's pretty laborious, but is there any way you could possibly put together a sample of how you would go about it? Pretty please? :)
– Jay
Feb 19 '21 at 22:35

I have an answer here where I use Compare nodes to create a switch with a default case. At this point I have to point out that there is overlap at the minima and maxima of these nodes, and the winner is dictated by the order of the MixRGB nodes.

For example, a value of .2 activates the code path of both the first and second Compare nodes, but the yellow color would win out.

An If is just a lerp (linear interpolation) with boolean (1 or 0) inputs. That's the easy way to think of it.

And a lerp is, currently, most easily implemented with map range node: I've labelled value nodes with "ELSE" and "IF" to make it clear which is which. So what I'm doing here is saying, If UV.x > 0.5 then 1.0 else 0.0.

So let's look at one arm of your actual code:

if( r === max )
h = ( g - b ) / delta;      // between yellow & magenta
else if( g === max )
h = 2 + ( b - r ) / delta;  // between cyan & yellow
else
h = 4 + ( r - g ) / delta;  // between magenta & cyan

Now, let's rewrite that a bit, because the order of operations isn't particularly clear from the way that code is written:

if( r === max ) {
h = ( g - b ) / delta;      // between yellow & magenta
}
else {
if( g === max ) {
h = 2 + ( b - r ) / delta;  // between cyan & yellow
}
else {
h = 4 + ( r - g ) / delta;  // between magenta & cyan
}
}

With the reordering, we can see that our else if is really a nested if statement. Let's implement it in nodes: Using labelled value nodes for our inputs, and assuming that === means equality comparison (I'm not familiar with that usage.) And our output is of course h, which is the only thing that snippet assigns.

• I'm going to have to study your implementation. The solution I came up with is a lot more complex. This looks much more graceful. I really, really appreciate your help! If you wouldn't mind taking a look at another question of mine: blender.stackexchange.com/questions/212430/… I would really like to see how you would approach that as well.
– Jay
Feb 20 '21 at 0:05
• @Jay I took a quick look. Think about it this way: IF i = 1 then r=v ELSE IF i = 2 r = q ELSE if i = 3.... Operating in parallel with IF i = 1 then g= t.... It's going to be a complete mess, that's just something you're going to have to accept when trying to implement branching logic in nodes. Feb 20 '21 at 0:08
• Thanks much for looking. I'm still just stuck. I understand that it's just a branching if/else construct. But the part that gets me is assigning multiple different values to the RGB outputs depending on the value of I.
– Jay
Feb 20 '21 at 0:11