Created
April 20, 2025 11:27
-
-
Save juliendargelos/dee3d4ee0ff67c203b9f45cff19701cf to your computer and use it in GitHub Desktop.
Adaptation of the native GLSL mix function, leveraging native GLSL vector algebra and swizzling for cyclic linear or smooth (sigmoid) interpolation across vector components. Also includes 2-3-4-colors cyclic gradient functions based on cycleMix and smoothCycleMix.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include cycle-mix.glsl | |
vec4 cycleGradient(vec4 a, vec4 b, float x) { | |
x *= 0.5; | |
return vec4( | |
cycleMix(vec2(a.x, b.x), x), | |
cycleMix(vec2(a.y, b.y), x), | |
cycleMix(vec2(a.z, b.z), x), | |
cycleMix(vec2(a.w, b.w), x) | |
); | |
} | |
vec4 cycleGradient(vec4 a, vec4 b, vec4 c, float x) { | |
x *= 0.6666667; | |
return vec4( | |
cycleMix(vec3(a.x, b.x, c.x), x), | |
cycleMix(vec3(a.y, b.y, c.y), x), | |
cycleMix(vec3(a.z, b.z, c.z), x), | |
cycleMix(vec3(a.w, b.w, c.w), x) | |
); | |
} | |
vec4 cycleGradient(vec4 a, vec4 b, vec4 c, vec4 d, float x) { | |
x *= 0.75; | |
return vec4( | |
cycleMix(vec4(a.x, b.x, c.x, d.x), x), | |
cycleMix(vec4(a.y, b.y, c.y, d.y), x), | |
cycleMix(vec4(a.z, b.z, c.z, d.z), x), | |
cycleMix(vec4(a.w, b.w, c.w, d.w), x) | |
); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Linear interpolation between the components of a vector based on x ∈ [0; 1], | |
* cycling through its components then wrapping back to the first one, | |
* and repeating periodically when x ∈ ℝ \ [0; 1]. | |
*/ | |
float cycleMix(vec2 v, float x) { | |
float t = mod(x, 1.) * 2.; | |
float i = floor(t); | |
return dot(mix(v, v.yx, fract(t)), vec2( | |
1. - step(1., i), | |
step(1., i) | |
)); | |
} | |
float cycleMix(vec3 v, float x) { | |
float t = mod(x, 1.) * 3.; | |
float i = floor(t); | |
return dot(mix(v, v.yzx, fract(t)), vec3( | |
1. - step(1., i), | |
step(1., i) * (1. - step(2., i)), | |
step(2., i) | |
)); | |
} | |
float cycleMix(vec4 v, float x) { | |
float t = mod(x, 1.) * 4.; | |
float i = floor(t); | |
return dot(mix(v, v.yzwx, fract(t)), vec4( | |
1. - step(1., i), | |
step(1., i) * (1. - step(2., i)), | |
step(2., i) * (1. - step(3., i)), | |
step(3., i) | |
)); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include smooth-cycle-mix.glsl | |
vec4 smoothCycleGradient(vec4 a, vec4 b, float x) { | |
x *= 0.5; | |
return vec4( | |
smoothCycleMix(vec2(a.x, b.x), x), | |
smoothCycleMix(vec2(a.y, b.y), x), | |
smoothCycleMix(vec2(a.z, b.z), x), | |
smoothCycleMix(vec2(a.w, b.w), x) | |
); | |
} | |
vec4 smoothCycleGradient(vec4 a, vec4 b, vec4 c, float x) { | |
x *= 0.6666667; | |
return vec4( | |
smoothCycleMix(vec3(a.x, b.x, c.x), x), | |
smoothCycleMix(vec3(a.y, b.y, c.y), x), | |
smoothCycleMix(vec3(a.z, b.z, c.z), x), | |
smoothCycleMix(vec3(a.w, b.w, c.w), x) | |
); | |
} | |
vec4 smoothCycleGradient(vec4 a, vec4 b, vec4 c, vec4 d, float x) { | |
x *= 0.75; | |
return vec4( | |
smoothCycleMix(vec4(a.x, b.x, c.x, d.x), x), | |
smoothCycleMix(vec4(a.y, b.y, c.y, d.y), x), | |
smoothCycleMix(vec4(a.z, b.z, c.z, d.z), x), | |
smoothCycleMix(vec4(a.w, b.w, c.w, d.w), x) | |
); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Sigmoid interpolation between the components of a vector based on x ∈ [0; 1], | |
* cycling through its components then wrapping back to the first one, | |
* and repeating periodically when x ∈ ℝ \ [0; 1]. | |
*/ | |
float smoothCycleMix(vec2 v, float x) { | |
float t = mod(x, 1.) * 2.; | |
float i = floor(t); | |
return dot(mix(v, v.yx, smoothstep(0., 1., fract(t))), vec2( | |
1. - step(1., i), | |
step(1., i) | |
)); | |
} | |
float smoothCycleMix(vec3 v, float x) { | |
float t = mod(x, 1.) * 3.; | |
float i = floor(t); | |
return dot(mix(v, v.yzx, smoothstep(0., 1., fract(t))), vec3( | |
1. - step(1., i), | |
step(1., i) * (1. - step(2., i)), | |
step(2., i) | |
)); | |
} | |
float smoothCycleMix(vec4 v, float x) { | |
float t = mod(x, 1.) * 4.; | |
float i = floor(t); | |
return dot(mix(v, v.yzwx, smoothstep(0., 1., fract(t))), vec4( | |
1. - step(1., i), | |
step(1., i) * (1. - step(2., i)), | |
step(2., i) * (1. - step(3., i)), | |
step(3., i) | |
)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment