Effect: Hue Slider

New releases and general discussions.

Post » Sun Mar 08, 2009 5:08 am

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:

[code:29wyuobn]
//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.
B
2
S
2
G
4
Posts: 254
Reputation: 1,958

Post » Sun Mar 08, 2009 8:16 am

That'd be really cool to have!
B
6
S
2
G
3
Posts: 520
Reputation: 2,690

Post » Sun Mar 08, 2009 3:26 pm

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
B
52
S
7
G
6
Posts: 1,945
Reputation: 7,610

Post » Sun Mar 08, 2009 3:28 pm

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.
B
6
S
2
G
3
Posts: 520
Reputation: 2,690

Post » Sun Mar 08, 2009 5:42 pm

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

you could use lerp for the value picking and stuff
B
52
S
7
G
6
Posts: 1,945
Reputation: 7,610

Post » Sun Mar 08, 2009 7:10 pm

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.


the only difference between any of these are their hue values in photoshop -- a single slider.
B
2
S
2
G
4
Posts: 254
Reputation: 1,958

Post » Sun Mar 08, 2009 7:32 pm

Tadah! Take a look here. I'll take my billion dollar fee, now. ;)
Moderator
B
98
S
37
G
19
Posts: 1,584
Reputation: 17,817

Post » Sun Mar 08, 2009 7:39 pm

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



for things that are one color, your shader will work perfectly though :D
B
2
S
2
G
4
Posts: 254
Reputation: 1,958

Post » Sun Mar 08, 2009 10:42 pm

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.
Moderator
B
98
S
37
G
19
Posts: 1,584
Reputation: 17,817

Post » Sun Mar 08, 2009 10:56 pm

oh wow. thanks a ton man.
B
2
S
2
G
4
Posts: 254
Reputation: 1,958

Next

Return to Construct Classic Discussion

Who is online

Users browsing this forum: No registered users and 3 guests