Effect: Hue Slider

This forum is currently in read-only mode.
  • hue sliders are very helpful for generating alternate colors from the same assets.

    at first i thought i may be able to edit the invert effect to let me basically slide the hue value, but after realizing a hue shift effect will likely rely on rgb > HSV/HSL > rgb translations, and not really being a programmer myself, i've given up on the possibility of writing this pixel shader myself.

    here's an algorithm to convert RGB to HSV and HSV to RGB: http://www.cs.rit.edu/~ncs/color/t_convert.html

    i've also found a non-construct pixel shader that can apparently let the user control H, S, V values, so perhaps this can serve to give someone a headstart:

    //transforms
    float4x4 tW: WORLD; //the models world matrix
    float4x4 tV: VIEW; //view matrix as set via Renderer (DX9)
    float4x4 tP: PROJECTION; //projection matrix as set via Renderer (DX9)
    float4x4 tWVP: WORLDVIEWPROJECTION;
    
    //texture input
    texture Tex <string uiname="Texture";>;
    sampler Samp = sampler_state //sampler for doing the texture-lookup
    {
       Texture   = (Tex);          //apply a texture to the sampler
       MipFilter = LINEAR;         //sampler states
       MinFilter = LINEAR;
       MagFilter = LINEAR;
    };
    float4x4 tTex: TEXTUREMATRIX <string uiname="Texture Transform";>;
    float HueShift      = 0.07;
    float SaturationShift    = 0.07;
    float ValueShift  = 0.07;
    //texture transformation marked with semantic TEXTUREMATRIX to achieve symmetric transformations
    
    struct vs2ps
    {
       float4 Pos   : POSITION;
       float4 TexCd : TEXCOORD0;
    };
    // -------------------------------------------------------------------------
    // VERTEXSHADERS
    // -------------------------------------------------------------------------
    
    vs2ps VS( float4 Pos    : POSITION, float4 TexCd  : TEXCOORD0 )
    {
       //inititalize all fields of output struct with 0
       vs2ps Out = (vs2ps)0;
    
       //transform position
       Out.Pos = mul(Pos, tWVP);
    
       //transform texturecoordinates
       Out.TexCd = mul(TexCd, tTex);
    
       return Out;
    }
    
    // -------------------------------------------------------------------------
    // PIXELSHADERS:
    // -------------------------------------------------------------------------
    float4 simpas(vs2ps In): COLOR
    {
     float4 col = tex2D(Samp, In.TexCd);
     return col;
    }
    
    float4 shift(vs2ps In): COLOR
    
    {
    float4 col = tex2D(Samp, In.TexCd);
    ////////////////////////////////////////
    //Parameter Definition for
    //HSV conversion  of Texture
    ////////////////////////////////////////
    double  r, g, b, delta;
    double  colorMax, colorMin;
    double  h=0, s=0, v=0;
    
    //HSV-Value Texture
        r = col[0];
        g = col[1];
        b = col[2];
    
        colorMax = max (r,g);
        colorMax = max (colorMax,b);
        colorMin = min (r,g);
        colorMin = min (colorMin,b);
        v = colorMax;               // this is the result
        
    //HSV-Saturation  of Texture
        if (colorMax != 0)
        { s = (colorMax - colorMin) / colorMax; }
    
    //HSV-Hue  of Texture
        if (s != 0) // if not achromatic
        {
            delta = colorMax - colorMin;
            if (r == colorMax){ h = (g-b)/delta; }
            else if (g == colorMax){  h = 2.0 + (b-r) / delta; }
            else { h = 4.0 + (r-g)/delta; }
            h *= 60;
            if( h < 0){ h +=360; }
            h = h / 360.0;    // moving h to be between 0 and 1.
        }
    
    //////////////////////////////////////////////////////
    // the calculation ///////////////////////////////////
    //////////////////////////////////////////////////////
    
            h+=HueShift;
            if (h>1) h-=1;
    
            s+=SaturationShift;
            if (s>1) s-=1;
            
            v+=ValueShift;
            if (v>1) v-=1;
    
     //////////////////////////////////////////////////////
    //
    // hsv  to rgb conversion
    /////////////////////////////////////////////////////
    
        double  f,p,q,t;
    
        double  rN=0,gN=0,bN=0;
        double  i;
               h *= 360;
        if (s == 0) {if (v != 0)    {col = v;}}
        else        {if (h == 360.0){h=0;}
    
            h /=60;
            i = floor (h);
            f = h-i;
            p = v * (1.0 - s);
            q = v * (1.0 - (s * f));
            t = v * (1.0 - (s * (1.0 -f)));
    
            if (i == 0)      { rN = v; gN = t; bN = p; }
            else if (i == 1) { rN = q; gN = v; bN = p; }
            else if (i == 2) { rN = p; gN = v; bN = t; }
            else if (i == 3) { rN = p; gN = q; bN = v; }
            else if (i == 4) { rN = t; gN = p; bN = v; }
            else if (i == 5) { rN = v; gN = p; bN = q; }
    
            col.r = rN;
            col.g = gN;
            col.b = bN;
        }
    
     return col;
    }
    
    // -------------------------------------------------------------------------
    // TECHNIQUES:
    // -------------------------------------------------------------------------
    
    technique simplePass //name for the technique pin
    {
       pass P0
       {
           VertexShader = compile vs_1_1 VS();
           PixelShader  = compile ps_1_1 simpas();
       }
    }
    
    technique shiftHSV //name for the technique pin
    {
       pass P0
       {
           VertexShader = compile vs_1_1 VS();
           PixelShader  = compile ps_2_a shift();
       }
    }
    [/code:29wyuobn]
    
    edit: i'm imagining the "slider" would just be a percent parameter, but i may prefer a float variable with a functional range up to 360.
  • That'd be really cool to have!

  • why dont you just use a filter for recolour portions (i.e the red/blue/green on a tank in an rts depending on what colour you are) and make those portions a different sprite

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • What? Say I wanna create a layout with a blue sky in the back - and as I walk across the layout, the sky gradually becomes darker and greener. That sorta stuff would work nicely with a HSV Slider that could be triggered.

  • why dont you use rgb(value,value,value,)

    you could use lerp for the value picking and stuff

  • it's just more of a pain. open up a brightly colored image in photoshop. go to image>adjustments>color balance and play with the sliders to get alternate colors. then try image>adjustments>hue/saturation and mess with the hue slider -- you'll see how much more convenient it is.

    <img src="http://upload.dfyb.net/uploaded/hue_slider.jpg">

    the only difference between any of these are their hue values in photoshop -- a single slider.

  • Tadah! Take a look here. I'll take my billion dollar fee, now.

  • works well. only thing is that it sets the hue the same for every pixel, rather than adjust hue for each pixel based on the original hue. you can see what i mean here -- your shader result is on right

    <img src="http://upload.dfyb.net/uploaded/hue_compare.jpg">

    for things that are one color, your shader will work perfectly though

  • Just fixed it up to where the hue is different for each pixel depending on their original color. I even tested it with your example and it looks exactly like the hue tints you did in PhotoShop. Just redownload it from the main thread.

  • oh wow. thanks a ton man.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)