uniform vec2 orbit[4096]; uniform vec2 offset = vec2(0, 0); uniform float zoom = 300; uniform int iterations = 256; uniform int antialias = 0; vec2 mul(vec2 a, vec2 b) { return vec2(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x); } vec2 sq(vec2 a) { return vec2(a.x*a.x - a.y*a.y, 2 * a.x * a.y); } float abssq(vec2 a) { return a.x*a.x + a.y*a.y; } int brot(vec2 c) { vec2 dz = vec2(0, 0); int ri = 0; for (int i = 0; i < iterations; i++) { dz = mul(mul(vec2(2, 0), dz), orbit[ri]) + sq(dz) + c; ri++; vec2 z = orbit[ri] + dz; if (abssq(z) > 4) return i; if (abssq(z) < abssq(dz) || abssq(orbit[ri]) > 4) { dz = z; ri = 0; } } return -1; } vec3 hsv2rgb(vec3 c) { vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); } vec3 color_at(vec2 screen_pos) { vec2 pos = offset + screen_pos / zoom; int i = brot(pos); if (i >= 0) { float it = i; float ri = it / iterations; float h = mod(0.4 + log(1 + it) / 12.0, 1.0); float s = 0.6 + sin(it / 30) * 0.2; float v = 0.1 + pow(ri, 1.01) * 2.0; return hsv2rgb(vec3(h, s, v)); } else { return vec3(0, 0, 0); } } vec4 effect(vec4 color, Image t, vec2 img_pos, vec2 screen_pos) { vec3 result = vec3(0, 0, 0); for (float x = 0; x < antialias; x++) { for (float y = 0; y < antialias; y++) { vec2 pos = screen_pos - 0.5 + vec2(x, y) / antialias; result += color_at(pos) / (antialias * antialias); } } return vec4(result, 1); }