diff options
Diffstat (limited to 'mandelbrot.glsl')
| -rw-r--r-- | mandelbrot.glsl | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/mandelbrot.glsl b/mandelbrot.glsl new file mode 100644 index 0000000..42279bd --- /dev/null +++ b/mandelbrot.glsl @@ -0,0 +1,67 @@ +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); +} + |
