My original implementation was

float3 RGBtoHCY(in float3 RGB)

{

float3 HCV = RGBtoHCV(RGB);

float Y = dot(RGB, HCYwts);

if (HCV.y != 0)

{

float Z = dot(HUEtoRGB(HCV.x), HCYwts);

if (Y > Z)

{

Y = 1 - Y;

Z = 1 - Z;

}

HCV.y *= Z / Y;

}

return float3(HCV.x, HCV.y, Y);

}

As he points out:

I'll have to bow to David's superior knowledge on HCY usage as I've never actually used it in anger. So here's his improved version:It seems to me that you have an error in your RGB to HCY code, though. I was having some pixels always saturate to white, and after looking at Kuzma Shapran's original code I don't think the value of Y should actually be changed, only using the adjusted value of Y to calculate HCV.y. Additionally I think the check for 0 in the original code was meant to prevent divide by 0 errors, so should be using Y instead of HCV.y.

float3 RGBtoHCY(in float3 RGB)

{

float3 HCV = RGBtoHCV(RGB);

float Y = dot(RGB, HCYwts);

float Z = dot(HUEtoRGB(HCV.x), HCYwts);

if (Y < Z)

{

HCV.y *= Z / (Epsilon + Y);

}

else

{

HCV.y *= (1 - Z) / (Epsilon + 1 - Y);

}

return float3(HCV.x, HCV.y, Y);

}

I've updated the snippets page accordingly.