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); }