A nice way to render fractals like Julia o Mandelbrot sets of polynomials is to use the distance from the current pixel to the boundary of the set. This avoids the usual aliasing problem of rendering fractals, where details are just too small to be visible through the sampling of the image. Without going into details in this article (go to the math section for that), the distance to the Mandelbrot set can be computed through its Green function G(c) (or Hubbard-Douady potential), which is a continuous function. Therefore, according to the usual way to approximate distances to isosurfaces in continuous functions, we can estimate the distance to the fractal surface as
Basically this means than during our regular iteration loop we need to keep track of both Zn as usual and of its derivative Z'n. If we are rendering the standard Mandelbrot set with then simple derivation rules give and for a Julia set, float calcDistance( float a, float b ) { Complex c( a, b ); Complex z( 0.0f, 0.0f ); Complex dz( 0.0f, 0.0f ); float m2; for( int i=0; i<1024; i++ ) { dz = 2.0f*z*dz + 1.0f; z = z*z + c; m2 = Complex::ModuloSquared(z); if( m2>1e20f ) break; } // distance estimation: G/|G'| return sqrtf( m2/Complex::ModuloSquared(dz) )*0.5f*logf(m2); } |
The Mandelbrot set rendered with the distance formula.Click to enlarge |

The estimated distance can now be used to do coloring. The video on the right uses the distance to index into a color palette, while the images below simply remap the distance estimation to a grayscale value:

This is a realtime version of the algorithm, for reference: