Task 5 of 5
Here's the payoff. Take the exact loop you've built and flip the
roles: in a Julia set, z starts at the pixel and c is one
fixed complex number shared by every thread. Each choice of c is a different fractal —
c = 0 gives a plain disk, −0.7269 + 0.1889i a galaxy of spirals —
and the Mandelbrot set turns out to be the map of which c values give connected Julias.
Because c arrives as kernel arguments, changing it costs one function call — no recompiling. That's what makes those mesmerizing morphing-Julia animations: nudge c, redraw, repeat.
z from the pixel, add the arguments cRe, cIm each step, and keep
task 4's smooth shading (interior black).zr = xMin + x·step, zi = yMin + y·step (constants are wired up)cRe and cIm — not the pixel coordinatest = smooth / 100 through the same three-cosine palette as the last task; interior: blackrender() itTwo lines. Mandelbrot: z starts at 0 and c is the pixel. Julia: z starts at the pixel and c is the argument pair. The loop body, the guard, the shading — all identical.
Seed with
let zr = this.constants.xMin + x * this.constants.step;
(and likewise zi from y), then inside the loop use
… + cRe and … + cIm instead of px / py.
This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.