Skip to content
Snippets Groups Projects

GPU accelerated fractal zoom.

Merged Finn Bear requested to merge wgpu into main
7 files
+ 776
22
Compare changes
  • Side-by-side
  • Inline
Files
7
+ 79
0
struct ComputeParams {
width: u32;
height: u32;
center_x: f32;
center_y: f32;
zoom: f32;
};
[[group(0), binding(0)]] var<uniform> params: ComputeParams;
[[group(0), binding(1)]] var texture: [[stride(16)]] texture_storage_2d<rgba8unorm, write>;
fn mandelbrot(x: f32, y: f32, cutoff: f32) -> f32 {
var x1: f32 = 0.0;
var y1: f32 = 0.0;
var i: f32 = 0.0;
loop {
if (x1 * x1 + y1 * y1 > 16.0 || i >= cutoff) {
break;
}
let x_tmp: f32 = x1 * x1 - y1 * y1 + x;
y1 = 2.0 * x1 * y1 + y;
x1 = x_tmp;
i = i + 1.0;
}
var fract = 1.0 - log(log(sqrt(max(1.001, x1 * x1 + y1 * y1)))) / log(2.0);
return (i + fract) / cutoff;
}
[[stage(compute), workgroup_size(8, 8)]]
fn main([[builtin(global_invocation_id)]] global_id: vec3<u32>) {
let X: u32 = global_id.x;
let Y: u32 = global_id.y;
let W: u32 = params.width;
let H: u32 = params.height;
if (X >= W || Y >= H) {
return;
}
let aspect = f32(W) / f32(H);
let nx = f32(X) / f32(W) - 0.5;
let ny = f32(Y) / f32(H) - 0.5;
let fx = params.center_x + nx * params.zoom * aspect;
let fy = params.center_y + ny * params.zoom;
let max_iter = min(270.0, 32.0 + sqrt(16.0 / params.zoom));
let o = params.zoom * 0.2 / f32(W);
let iter = pow((mandelbrot(fx + o, fy + o, max_iter) + mandelbrot(fx + o, fy - o, max_iter) + mandelbrot(fx - o, fy + o, max_iter) + mandelbrot(fx - o, fy - o, max_iter)) * 0.25, 1.0);
// https://flatuicolors.com/palette/defo
var amethyst = vec3<f32>(155.0/255.0, 89.0/255.0, 182.0/255.0);
var wet_asphalt = vec3<f32>(52.0/255.0, 73.0/255.0, 94.0/255.0);
var emerald = vec3<f32>(46.0/255.0, 204.0/255.0, 113.0/255.0);
var sunflower = vec3<f32>(241.0/255.0, 196.0/255.0, 15.0/255.0);
var alizarin = vec3<f32>(231.0/255.0, 76.0/255.0, 60.0/255.0);
var pomegranate = vec3<f32>(192.0/255.0, 57.0/255.0, 43.0/255.0);
var peter_river = vec3<f32>(52.0/255.0, 152.0/255.0, 219.0/255.0);
var midnight_blue = vec3<f32>(44.0/255.0, 62.0/255.0, 80.0/255.0);
let count: i32 = 8;
var stops = array<vec3<f32>, 8>(
midnight_blue,
alizarin,
wet_asphalt,
amethyst,
peter_river,
pomegranate,
sunflower,
vec3<f32>(0.1, 0.1, 0.1)
);
let i = i32(iter * f32(count - 1));
let color = mix(stops[i], stops[i + 1], smoothStep(f32(i) / f32(count - 1), f32(i + 1) / f32(count - 1), iter));
textureStore(texture, vec2<i32>(i32(X), i32(Y)), vec4<f32>(color.x, color.y, color.z, 1.0));
}
\ No newline at end of file
Loading