/* * Copyright (c) Camden Dixie O'Brien * SPDX-License-Identifier: AGPL-3.0-only */ #version 450 #extension GL_ARB_gpu_shader_fp64 : enable #define MAXITER 1000 layout(location = 0) out vec4 out_colour; layout(push_constant) uniform Constants { dvec2 img_size; dvec2 shift; double zoom; } params; vec2 ss_offsets[4] = vec2[]( vec2(-0.25, -0.25), vec2( 0.25, -0.25), vec2(-0.25, 0.25), vec2( 0.25, 0.25) ); dvec2 maptoz(vec2 xy) { dvec2 dxy = dvec2(xy); dvec2 uv = ((dxy / params.img_size.xy) * 4.0LF - 2.0LF); return params.zoom * uv + params.shift; } double mandelbrot(dvec2 c) { dvec2 z = dvec2(0.0LF, 0.0LF); for (int i = 0; i < MAXITER; ++i) { z = dvec2(z.x * z.x - z.y * z.y, 2.0LF * z.x * z.y) + c; if (length(z) > 2.0LF) return double(i) / double(MAXITER); } return 0.0; } vec3 colour(double i) { float fi = float(i); return vec3(fi, fi * fi, fi * fi * fi); } void main() { dvec2 c; vec3 col = vec3(0.0, 0.0, 0.0); for (int i = 0; i < 4; ++i) { c = maptoz(gl_FragCoord.xy + ss_offsets[i]); col += colour(mandelbrot(c)); } out_colour = vec4(col, 1.0); }