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.
No comments:
Post a Comment