I decided to write this shader as exercise. I am not sure how correct it is, so if you notice something wrong please tell me.
Used this article: forums.create.msdn.com/forums/t/61412.aspx as reference.
Screenshot:
Shader:
//Cg
#ifndef Epsilon
#define Epsilon 1e-5
#endif
float RGBtoHue(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, Epsilon);
float i = abs(float((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;
}
float3 RGBToHSV(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 V = M;
float S = C / max(V, Epsilon);
float H = RGBtoHue(color);
return float3(H, S, V);
}
float3 HueToRGB(float H, float3 hsv)
{
float C = hsv.z * hsv.y;
float Hn = H / 60;
float X = C * (1 - abs(fmod(Hn, 2) - 1));
float3 hul[7];
hul[0] = float3(0, 0, 0);
hul[1] = float3(C, X, 0);
hul[2] = float3(X, C, 0);
hul[3] = float3(0, C, X);
hul[4] = float3(0, X, C);
hul[5] = float3(X, 0, C);
hul[6] = float3(C, 0, X);
float i = floor(Hn);
return hul[i];
}
void vshader(
uniform float4x4 mat_modelproj,
in float4 vtx_position : POSITION,
out float4 l_position : POSITION,
uniform float4 outColor,
in float2 vtx_texcoord0 : TEXCOORD0,
out float2 l_texcoord0 : TEXCOORD0
)
{
l_position = mul(mat_modelproj, vtx_position);
l_texcoord0 = vtx_texcoord0;
}
void fshader(
out half4 o_color : COLOR,
in half2 l_texcoord0 : TEXCOORD0,
uniform sampler2D tex_0)
{
float hue;
float4 tex = tex2D(tex_0, l_texcoord0);
float3 newColor;
float r = tex[0];
float g = tex[1];
float b = tex[2];
// Calculate hue
if ((r >= g) && (g >= b))
{
hue = 60 * (g - b / r - b);
}
else if ((g > r) && (r >= b))
{
hue = 60 * (2 - (r - b / g - b));
}
else if ((g >= b) && (b > r))
{
hue = 60 * (2 + (b - r / g - r));
}
else if ((b > g) && (g > r))
{
hue = 60 * (4 - (g - r / b - r));
}
else if ((b > r) && (r >= g))
{
hue = 60 * (4 + (r - g / b - g));
}
else if ((r >= b) && (b > g))
{
hue = 60 * (6 - (b - g / r - g));
}
float3 hsv = RGBToHSV(tex.xyz);
newColor = HueToRGB(hue, hsv);
o_color = float4(newColor, tex[3]);
}