An attempt at a demo effect
Log in to post a comment.
#version 300 es
precision highp float;
uniform float iTime;
uniform vec2 iResolution;
out vec4 fragColor;
// 2×2 rotation matrix
mat2 rot(float a) {
float c = cos(a), s = sin(a);
return mat2(c, -s, s, c);
}
// a smooth palette generator
vec3 palette(float t) {
return vec3(
0.5 + 0.5 * cos(6.2831 * (t + 0.0)),
0.5 + 0.5 * cos(6.2831 * (t + 0.33)),
0.5 + 0.5 * cos(6.2831 * (t + 0.67))
);
}
// alternating concentric-ring pattern centered at `center`
float ringPattern(vec2 uv, vec2 center, float freq) {
float d = length(uv - center);
return step(0.5, fract(d * freq));
}
void main() {
// normalize coords to [-1,+1], correct aspect ratio
vec2 uv = (gl_FragCoord.xy / iResolution.xy) * 2.0 - 1.0;
uv.x *= iResolution.x / iResolution.y;
float t = iTime;
// time-varying frequencies: oscillate around base values
float f1 = 18.0 + 6.0 * sin(t * 0.7);
float f2 = 22.0 + 4.0 * cos(t * 0.9);
// moving centres
vec2 c1 = rot( t * 0.6) * vec2(0.3, 0.0);
vec2 c2 = rot(-t * 0.4) * vec2(0.4, 0.0);
// build each ring pattern
float p1 = ringPattern(uv, c1, f1);
float p2 = ringPattern(uv, c2, f2);
// XOR for moiré
float m = abs(p1 - p2);
// dynamic colours for each pattern
vec3 col1 = mix(
palette(fract(t * 0.1)), // colour A
palette(fract(t * 0.1 + 0.5)), // colour B
p1
);
vec3 col2 = mix(
palette(fract(t * 0.15 + 0.25)),
palette(fract(t * 0.15 + 0.75)),
p2
);
// blend patterns: show both but highlight moiré
vec3 color = mix(col1, col2, 0.5) * (0.5 + 0.5 * m);
fragColor = vec4(color, 1.0);
}