Skip to content

Instantly share code, notes, and snippets.

@behreajj
Last active August 11, 2018 13:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save behreajj/425d7033d6b6fc86eb3f17a56541a960 to your computer and use it in GitHub Desktop.
Save behreajj/425d7033d6b6fc86eb3f17a56541a960 to your computer and use it in GitHub Desktop.
Mobius Transformation Fragment Shader
precision mediump float;
precision mediump int;
// Uniforms
uniform float time;
uniform vec2 center;
uniform vec2 dimensions;
uniform vec2 a;
uniform vec2 b;
uniform vec2 c;
uniform vec2 d;
uniform vec4 clr0;
uniform vec4 clr1;
uniform vec4 clr2;
// Passed from vertex shader.
varying vec4 vertTexCoord;
// Unary functions.
float cxmodulussq(vec2 a) {
return dot(a, a);
}
vec2 cxreciprocal(vec2 a) {
return vec2(a.x, -a.y) / cxmodulussq(a);
}
// Binary functions.
vec2 cxmult(vec2 a, vec2 b) {
return vec2(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
}
vec2 cxdiv(vec2 a, vec2 b) {
return cxmult(a, cxreciprocal(b));
}
vec2 cxmobius(vec2 a, vec2 b, vec2 c, vec2 d, vec2 z) {
return cxdiv(cxmult(a, z) + b, cxmult(c, z) + d);
}
// Vector functions.
vec2 rotatez(vec2 a, float t) {
float c = cos(t);
float s = sin(t);
return vec2(c * a.x - s * a.y, c * a.y + s * a.x);
}
void main() {
vec2 coord01 = gl_FragCoord.xy / dimensions;
coord01.y = 1.0 - coord01.y;
// Static.
// vec2 mbcoord = 0.5 + cxmobius(a, b, c, d, coord01 - 0.5);
// Animated.
vec2 f = rotatez(c, time);
vec2 mbcoord = 0.5 + cxmobius(a, b, f, d, coord01 - 0.5);
// Find distance of transformed point from center.
// Modulate distance to keep it within the range [0, 1].
float len = mod(length(center - mbcoord), 1.0);
float threshold0 = step(len, 0.525);
float threshold1 = step(len, 0.25);
vec4 clrmix = mix(mix(clr1, clr0, threshold0), clr2, threshold1);
gl_FragColor = clrmix;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment