Suppose I have a texture, what I want to do is for each pixel, return only the biggest channel as 1 and the rest as 0.
For instance:
| INPUT | OUTPUT
------|-------------------------|-----------------
RGBA | (0.5, 0.3, 0.4, 0.3) | (1, 0, 0, 0)
RGBA | ( 0 , 0.8, 0.9, 1 ) | (0, 0, 0, 1)
I'm using shader graph and I'm searching for an optimal approach to avoid using a lot of nodes.
My thought was taking the maximum m of all channels, then let each channel ci = (ci >= m), so the channel greater equal to m would be 1 and the rest would be 0, but I'm guessing there might be a better/more performant way.
PS: If there are 2 or more channels with the same value, the correctness doesn't matter, is a problem of the texture. It's possible to suppose there will always be a channel with biggest value.
One possible option would be to add a small custom function node.
float check = -1;
if ( inputColour.x > check )
{
check = inputColour.x;
outputColour = float4(1,0,0,0);
}
if ( inputColour.y > check )
{
check = inputColour.y;
outputColour = float4(0,1,0,0);
}
if ( inputColour.z > check )
{
check = inputColour.z;
outputColour = float4(0,0,1,0);
}
if ( inputColour.w > check )
{
outputColour = float4(0,0,0,1);
}
When the colour is closer to "red", the node produces:
But as the closer gets closer to "blue", the node produces:
EDIT
Added in recognition of a better answer. As per @Daniel's comment, this code will produce the same results, but with NO if
statements. AND it's easier to read! Win-win.
float m = inputColour.x;
m = max(m, inputColour.y);
m = max(m, inputColour.z);
m = max(m, inputColour.w);
outputColour = float4 ( inputColour.x = inputColour.x >= m,
inputColour.x = inputColour.y >= m,
inputColour.x = inputColour.z >= m,
inputColour.x = inputColour.w >= m );