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


    Aug 07 2008 | 6:51 pm
    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?

    • Aug 07 2008 | 6:53 pm
      By The way, I STILL CANT EDIT MESSAGES, EVEN 0.5 NANO SECONDS AFTER I POSTED THEM. GOD I CANT STAND THE FORUM !~@#!@#
    • Aug 08 2008 | 8:29 am
      is it possible your code is right-multiplying the rotation matrices while the original code is left-multiplying?
      best- parag.
    • Aug 08 2008 | 10:24 am
      no nevermind.
    • Aug 08 2008 | 10:33 am
      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; }
    • Aug 08 2008 | 3:53 pm
      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.
    • Aug 08 2008 | 4:21 pm
      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 :)
    • Aug 08 2008 | 5:15 pm
      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...
    • Aug 08 2008 | 5:35 pm
      Or maybe this is actually what it should be? But how does gl_FragColor accept that 4x4 * 1x4 = 4x4?
      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...
    • Aug 08 2008 | 5:38 pm
      ok yea the last one i sent is what photoshop says.
      sorry for the confusion! :)
    • Jun 16 2009 | 3:39 am
      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
    • Sep 15 2010 | 1:58 pm
      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
    • Sep 16 2010 | 6:12 pm
      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
    • Mar 13 2014 | 5:43 am
      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.