Color Space Conversions
From XNAWiki
The following are conversions between various color spaces.
RGB-XYZ
#ifndef CONVERT_XYZ_RGB
#define CONVERT_XYZ_RGB
float3 XYZ_to_RGB(float3 XYZ)
{
static float3x3 XYZ_to_sRGB =
{
3.240479, -0.969256, 0.055648,
-1.537150, 1.875991, -0.204043,
-0.498535, 0.041556, 1.057311
};
return mul(XYZ, XYZ_to_sRGB);
}
float3 RGB_to_XYZ(float3 sRGB)
{
static float3x3 sRGB_to_XYZ =
{
0.4124564, 0.2126729, 0.0193339,
0.3575761, 0.7151522, 0.1191920,
0.1804375, 0.0721750, 0.9503041
};
return mul(sRGB, sRGB_to_XYZ);
}
#endifRGB-xyY
#ifndef CONVERT_xyY_RGB
#define CONVERT_xyY_RGB
float3 xyY_to_RGB(float3 xyY)
{
xyY.y = max(1e-6, xyY.y);
float3 XYZ;
XYZ.x = xyY.x * (xyY.z / xyY.y);
XYZ.y = xyY.z;
XYZ.z = (1 - xyY.x - xyY.y) * (xyY.z / xyY.y);
return XYZ_to_RGB(XYZ);
}
float3 RGB_to_xyY(float3 sRGB)
{
float3 XYZ = RGB_to_XYZ(sRGB);
float sum = max(1e-6, XYZ.x + XYZ.y + XYZ.z);
float3 result;
result.x = XYZ.x / sum;
result.y = XYZ.y / sum;
result.z = XYZ.y;
return result;
}
#endifRGB-Hue
- Note: this may not compile properly on all versions of the effect compiler, works fine on fxc fx_2_0 profile.
#ifndef CONVERT_HUE_RGB
#define CONVERT_HUE_RGB
float3 Hue_to_RGB(float H, float C)
{
float Hn = ((H * 360) / 60) % 6;
float X = C * (1 - abs((Hn % 2) - 1));
float3 hlu[] =
{
C, X, 0, // 0
X, C, 0, // 1
0, C, X, // 2
0, X, C, // 3
X, 0, C, // 4
C, 0, X // 5
};
int i = floor(Hn);
return hlu[i];
}
float RGB_to_Hue(float3 color)
{
float M = max(max(color.r, color.g), color.b);
float m = min(min(color.r, color.g), color.b);
float C = M - m;
float invC = 1 / max(C, 1e-6);
int i = abs((2 * (M == color.b)) - (M == color.g)) * (M != color.r);
float4 hlu = color.gbrg;
float Hn = ((hlu[i] - hlu[i + 1])) * invC;
float Hp = (2 * i) + ((M == color.r && color.g < color.b) * 6);
return (Hn + Hp) / 6;
}
#endifRGB-HSL
#ifndef CONVERT_HSL_RGB
#define CONVERT_HSL_RGB
float3 HSL_to_RGB(float3 hsl)
{
float C = (1 - abs(2 * hsl.b - 1)) * hsl.g;
float m = hsl.b - (0.5 * C);
return Hue_to_RGB(hsl.r, C) + m;
}
float3 RGB_to_HSL(float3 color)
{
float M = max(max(color.r, color.g), color.b);
float m = min(min(color.r, color.g), color.b);
float C = M - m;
float L = 0.5 * (M + m);
float S = C / max(abs((2 * (L > 0.5)) - (2 * L)), 1e-6);
float H = RGB_to_Hue(color);
return float3(H, S, L);
}
#endifRGB-HSV
#ifndef CONVERT_HSV_RGB
#define CONVERT_HSV_RGB
float3 HSV_to_RGB(float3 hsv)
{
float C = hsv.b * hsv.g;
float m = hsv.b - C;
return Hue_to_RGB(hsv.r, C) + m;
}
float3 RGB_to_HSV(float3 color)
{
float M = max(max(color.r, color.g), color.b);
float m = min(min(color.r, color.g), color.b);
float C = M - m;
return float3(RGB_to_Hue(color), C / max(1e-6, M), M);
}
#endif