The Mandelbrot set begins with an almost suspiciously small rule. Start with z = 0, choose a complex number c, and repeatedly calculate z = z * z + c. Some choices of c escape toward large values. Others remain bounded. Map the choices onto an image, and the boundary becomes an intricate shape.

A Unity compute-shader example caught my attention because the workload is so easy to divide. Each pixel represents one value of c. Its calculation doesn't need the result from the neighboring pixel. A GPU can process many of these independent sequences at once.

The core calculation can be expressed without a complex-number type:

x = 0; y = 0
repeat up to limit:
    if x*x + y*y > 4: stop
    nextX = x*x - y*y + cx
    y = 2*x*y + cy
    x = nextX

The temporary nextX matters. Both new components must use the old values. Updating x before calculating y changes the recurrence and therefore changes the object being drawn.

A compute shader maps dispatch indices to image coordinates and writes the result into an output texture. The host application must also account for work-group dimensions. If the image size isn't an exact multiple of the group size, extra invocations need a bounds check before writing. A mathematically correct loop can still corrupt the result if the indexing is wrong.

The apparent independence doesn't mean every pixel costs the same. A point far outside the set may escape after a few iterations. A point close to the boundary may consume the full budget. Neighboring GPU lanes that take different paths can reduce the efficiency of the group. The fractal is a nice introduction to the difference between parallel work and uniformly parallel work.

Color introduces another decision. A basic renderer colors escaping points by their iteration count and assigns a separate color to points that reach the limit. The latter category means not observed to escape within this budget. It is not a mathematical proof of membership. Increasing the limit can change the image near difficult regions.

Zooming eventually reveals the limits of numerical precision as well as the beauty of the boundary. Once nearby pixels map to indistinguishable floating-point coordinates, allocating more display pixels cannot recover the missing distinction. The rendering equation remains tiny, but its implementation has become a lesson in scheduling, indexing, approximation and number representation. That is a lot of useful ground for one picture.