Skip to content

Instantly share code, notes, and snippets.

@mairod
Last active August 9, 2026 01:04
Show Gist options
  • Select an option

  • Save mairod/a75e7b44f68110e1576d77419d608786 to your computer and use it in GitHub Desktop.

Select an option

Save mairod/a75e7b44f68110e1576d77419d608786 to your computer and use it in GitHub Desktop.
Optimised Hue shift function in GLSL
vec3 hueShift( vec3 color, float hueAdjust ){
const vec3 kRGBToYPrime = vec3 (0.299, 0.587, 0.114);
const vec3 kRGBToI = vec3 (0.596, -0.275, -0.321);
const vec3 kRGBToQ = vec3 (0.212, -0.523, 0.311);
const vec3 kYIQToR = vec3 (1.0, 0.956, 0.621);
const vec3 kYIQToG = vec3 (1.0, -0.272, -0.647);
const vec3 kYIQToB = vec3 (1.0, -1.107, 1.704);
float YPrime = dot (color, kRGBToYPrime);
float I = dot (color, kRGBToI);
float Q = dot (color, kRGBToQ);
float hue = atan (Q, I);
float chroma = sqrt (I * I + Q * Q);
hue += hueAdjust;
Q = chroma * sin (hue);
I = chroma * cos (hue);
vec3 yIQ = vec3 (YPrime, I, Q);
return vec3( dot (yIQ, kYIQToR), dot (yIQ, kYIQToG), dot (yIQ, kYIQToB) );
}
@OwenTheProgrammer

Copy link
Copy Markdown

If you align the white-point with the Z-axis, rotate around Z, then undo the first reorientation (M R M*)
you can (after a fair amount of algebra and trig) get this version as well.

vec3 hue_shift(vec3 c, float angle) {
    const vec3 OFFSETS = PI * vec3(0./3., 2./3., 4./3.);
    vec3 ct = (1./3.) + (2./3.) * cos(angle + OFFSETS);
    return (c.rgb * ct.x) + (c.gbr * ct.y) + (c.brg * ct.z);
}

https://www.desmos.com/3d/w6lx6thiga

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment