Hue shader

Return to Code Snippets

Hue shader

Postby TaeZ » Mon Mar 19, 2012 4:40 pm

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: http://en.wikipedia.org/wiki/Hue and this thread: http://forums.create.msdn.com/forums/t/61412.aspx as reference.

Screenshot:

Image

Shader:

Code: Select all
//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]);
}


TaeZ
 
Posts: 56
Joined: Fri Apr 08, 2011 10:25 am

Postby rdb » Tue Mar 20, 2012 12:48 pm

Just keep in mind that conditionals like "if" are very expensive in shaders. You're probably better off using the technique described in the linked thread.
rdb
 
Posts: 8636
Joined: Mon Dec 04, 2006 5:58 am
Location: Netherlands


Return to Code Snippets

Who is online

Users browsing this forum: No registered users and 0 guests