Hue Shader – kind of works, anyone want to take a stab at it?

Aug 7, 2008 at 6:51pm

Hue Shader – kind of works, anyone want to take a stab at it?

Hello..

I noticed there was a lack of a hue rotation shader, which makes certain things difficult. I took a stab at it, and it … kind of works. Im not certain what I am doing wrong, and frankly, kindof moved on. So I post it here for those who want to give it a shot and repair it:

// http://www.graficaobscura.com/matrix/index.html – Hue rotation Matrix calculations.

This should be pretty straightforward, so I assume im making an assumption I should not be about either the linear RGB colorspace (which, im 99 % sure is what textures are usually handed off as),

Other than that, anyone? Beuller?

#39196
Aug 7, 2008 at 6:53pm

By The way, I STILL CANT EDIT MESSAGES, EVEN 0.5 NANO SECONDS AFTER I POSTED THEM. GOD I CANT STAND THE FORUM !~@#!@#

#137646
Aug 8, 2008 at 8:29am

is it possible your code is right-multiplying the rotation matrices
while the original code is left-multiplying?

best-
parag.

#137647
Aug 8, 2008 at 10:24am

no nevermind.

#137648
Aug 8, 2008 at 10:33am

is this right?

// based on “Hue Rotation while preserving luminance”
// http://www.graficaobscura.com/matrix/index.html
// Paul Haeberli
//
// ported to glsl by vade

uniform float hue;

// define our varying texture coordinates
varying vec2 texcoord0;
// define our rectangular texture samplers
uniform sampler2DRect tex0;

// no need to compute these…
const float sqrt2 = 1.414213562373095;
const float sqrt3 = 1.732050807568877;
const float oneoversqrt2 = 0.707106781186548;
const float oneoversqrt3 = 0.577350269189626;

//const vec4 lumcoeff = vec4(0.299,0.587,0.114, 1.0);
const vec4 lumcoeff = vec4(0.3086,0.6094,0.0820, 1.0);

const float zsx = lumcoeff.x/lumcoeff.z;
const float zsy = lumcoeff.y/lumcoeff.z;

// matrix functions.

mat4 ident = mat4(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);

// red
mat4 rotateXMat(float rs, float rc)
{
return mat4(1.0, 0.0, 0.0, 0.0,
0.0, rc, rs, 0.0,
0.0, -rs, rc, 0.0,
0.0, 0.0, 0.0, 1.0);
}

// green
mat4 rotateYMat(float rs, float rc)
{
return mat4(rc, 0.0, -rs, 0.0,
0.0, 1.0, 0.0, 0.0,
rs, 0.0, rc, 0.0,
0.0, 0.0, 0.0, 1.0);
}

// blue
mat4 rotateZMat( float rs, float rc)
{
return mat4(rc, rs, 0.0, 0.0,
-rs, rc, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
}

mat4 shearZMatrix(float dx, float dy)
{
return mat4(1.0, 0.0, dx, 0.0,
0.0, 1.0, dy, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
}

vec4 xformpnt(mat4 matrix, vec4 inputVec)
{

return vec4( inputVec.x*matrix[0][0] + inputVec.y*matrix[1][0] +
inputVec.z*matrix[2][0] + matrix[3][0],
inputVec.x*matrix[0][1] + inputVec.y*matrix[1][1] +
inputVec.z*matrix[2][1] + matrix[3][1],
inputVec.x*matrix[0][2] + inputVec.y*matrix[1][2] +
inputVec.z*matrix[2][2] + matrix[3][2], 1.0);
}

void main (void)
{

vec4 inputVec = texture2DRect(tex0, texcoord0);

// setup our transform mat – cant convert a const
mat4 transformMat = ident;

// rotate grey vector into positive Z
transformMat = rotateXMat(oneoversqrt2, oneoversqrt2) * transformMat;
transformMat = rotateYMat(-oneoversqrt3, sqrt2/sqrt3) * transformMat;

// shear to preserve lumanince
vec4 something = xformpnt(transformMat, inputVec);
float zsx = something.x/something.z;
float zsy = something.x/something.z;
transformMat = shearZMatrix(zsx,zsy) * transformMat;

// rotate hue, make angle input in degrees

float hue_rs = sin(radians(hue));
float hue_rc = cos(radians(hue));
transformMat = rotateZMat(hue_rs, hue_rc) * transformMat;

// unshear to preserve luminance
transformMat = shearZMatrix(-zsx,-zsy) * transformMat;

// unrotate
transformMat = rotateYMat(oneoversqrt3, sqrt2/sqrt3 ) * transformMat;
transformMat = rotateXMat(-oneoversqrt2, oneoversqrt2) * transformMat;

// do the hue transformation on our pixels
inputVec *= transformMat;

// convert to a vec with proper rgb values from our mat4.

// gl_FragColor = vec4(input0Mat[0][0], input0Mat[1][1],
input0Mat[2][2], input0Mat[3][3] );

gl_FragColor = inputVec;
}

#137649
Aug 8, 2008 at 3:53pm

Looks like we have a winner! Great stuff. Ill upload a zip with everything bundled, with credits to you in the source, of course. Thanks, I know a few folks who will really appreciate this.

#137650
Aug 8, 2008 at 4:21pm

Here is the full shader jxs with vert and frag. I did not include an example/help patch.

The only parameter is ‘hue’, in degrees.

Thanks again PKM. I noticed your fixes do a bunch of additional matrix multiplies in there. Nice catches. :) This actually is of great help with some other stuff im working on :)

#137651
Aug 8, 2008 at 5:15pm

Sorry vade- I had a serious type in there originally with an x instead
of a y and not using the lumcoeffs. Just change these lines:

vec4 something = xformpnt(transformMat, inputVec);
float zsx = something.x/something.z;
float zsy = something.x/something.z;
transformMat = shearZMatrix(zsx,zsy) * transformMat;

to:

vec4 something = xformpnt(transformMat, lumcoeff);
float zsx = something.x/something.z;
float zsy = something.y/something.z;
transformMat = shearZMatrix(zsx,zsy) * transformMat;

Though to be honest, it looks more interesting with the typo…

#137652
Aug 8, 2008 at 5:35pm

Or maybe this is actually what it should be? But how does gl_FragColor
accept that 4×4 * 1×4 = 4×4?

vec4 inputVec = texture2DRect(tex0, texcoord0);

// setup our transform mat – cant convert a const
mat4 transformMat = ident;

// rotate grey vector into positive Z
transformMat = rotateXMat(oneoversqrt2, oneoversqrt2) * transformMat;
transformMat = rotateYMat(-oneoversqrt3, sqrt2/sqrt3) * transformMat;

// shear to preserve lumanince
vec4 something = xformpnt(transformMat, lumcoeff);
float zsx = something.x/something.z;
float zsy = something.y/something.z;
transformMat = shearZMatrix(zsx,zsy) * transformMat;

// rotate hue, make angle input in degrees

float hue_rs = sin(radians(hue));
float hue_rc = cos(radians(hue));
transformMat = rotateZMat(hue_rs, hue_rc) * transformMat;

// unshear to preserve luminance
transformMat = shearZMatrix(-zsx,-zsy) * transformMat;

// unrotate
transformMat = rotateYMat(oneoversqrt3, sqrt2/sqrt3 ) * transformMat;
transformMat = rotateXMat(-oneoversqrt2, oneoversqrt2) * transformMat;

// do the hue transformation on our pixels
inputVec = transformMat * inputVec;

// convert to a vec with proper rgb values from our mat4.

gl_FragColor = inputVec;

Ok I’m checking gimp/ps in a second to see what it’s really supposed
to look like…

#137653
Aug 8, 2008 at 5:38pm

ok yea the last one i sent is what photoshop says.

sorry for the confusion! :)

#137654
Jun 16, 2009 at 3:39am

Hi,

I just tried loading this shader into a jit.gl.slab, and for some reason everything just passes through completely unaffected. Sending “param hue $1″ doesn’t seem to do anything. Any thoughts as to why this might be the case?

.mmb

#137655
Sep 15, 2010 at 1:58pm

I tried your shader and I got the error: “jit.gl.shader: error reading shader xml file”

I think it misses some part of the codes to make it working… I’m quite beginner in coding shader…

could you send the whole finale version of the shader please?

Thanks

#137656
Sep 16, 2010 at 6:12pm

Yeah I tried taking a stab at this one a few weeks ago…if you get stuck in a bind without a working shader and need something similar and are on a mac..I use this: [jit.gl.imageunit @fx "Hue Adjust"] ..the imageunits can be useful in certain situations, but a normal glsl shader would be nice too..will just take some time for vade to come back around here, he still comes though

#137657
Mar 12, 2014 at 10:43pm

Hi guys,
I needed something like this for a project of mine and was grateful to find this post. However it seems C74 has changed up the forums (now on WordPress) and lost the attachments for this thread in the process. I’ve pieced the working .jxs back together from PKM’s post and some of the the other stock color shaders. Please find the shader (just install in the jitter-shaders/color directory) and a quick test patch for it attached. Hope this is useful for future users.

I’m not sure if this version corrects for luminance shift across hue (the human eye is apparently not equally sensitive to all shades) but I don’t much mind since I’m using it for special effects rather than corrective editing.

Apparently the new forums don’t allow .jxs uploads; just remove the .txt extension and install normally.

#283612

You must be logged in to reply to this topic.