Fast Mandelbrot Renderer

Published on 13 November 2008

Here is another version of the classic Mandelbrot set, however this one runs fast enough in Pixel Bender for real-time zooming all the way down to the limit of the floating point number precision (at which point you get some glitchy goodness).

Adobe recently launched the Pixel Bender Toolkit, which is a high-performance graphics processing language for image processing. It will offload the image processing to the GPU enabling very high performance operations. 

You will need to install the Pixel Bender Toolkit (available as a free download here) and then copy & paste in the code below.

Some pixel bender scripts can be compiled into filters than can be used within Flash 10 applications. However, Flash doesn't yet support filters with loops like this one, so we won't have a super-charged Flash fractal explorer just yet.

/**
* Mandelbrot.pbk
*
* Copyright (c) 2008 Tom Beddard
* http://www.subblue.com
*
* Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
*
*
* Tips:
* - Use the centerPreset option to jump to interesting parts of the Mandelbrot set.
* - Increase the maxIterations option to increase detail on high zooms.
*
* As loops aren't supported with Hydra code it curently isn't possible to export this
* for use in Flash.
*/

<languageVersion: 1.0;>

kernel Mandelbrot
< namespace : "com.subblue.filters";
vendor : "Tom Beddard";
version : 1;
description : "Mandelbrot set renderer";
>

#define BAILOUT 10.0

{
output pixel4 dst;

parameter int2 size
<
minValue:int2(100, 100);
maxValue:int2(1000, 1000);
defaultValue:int2(640, 480);
>;

parameter float2 center
<
minValue:float2(-2.0, -1.0);
maxValue:float2(2.0, 1.0);
defaultValue:float2(-0.5, 0.0);
>;

parameter float2 centerOffset
<
minValue:float2(-1.0, -1.0);
maxValue:float2(1.0, 1.0);
defaultValue:float2(0.0, 0.0);
>;

parameter int centerPreset
<
minValue:0;
maxValue:4;
defaultValue:0;
>;

parameter float zoomMajor
<
minValue:0.0;
maxValue:20.0;
defaultValue:0.0;
>;

parameter float zoomMinor
<
minValue:0.0;
maxValue:10.0;
defaultValue:0.0;
>;

parameter int maxIterations
<
minValue:20;
maxValue:800;
defaultValue:200;
>;

region generated()
{
return region(float4(0, 0, size.x, size.y));
}

void
evaluatePixel()
{
pixel4 p;
float aa, bb, zz, twoab;
float x0 = center.x;
float y0 = center.y;

// Use a center preset to find some nice parts of the Mandelbrot set
if (centerPreset == 1) {
x0 = -0.742522478103764;
y0 = -0.143708014488453;
} else if (centerPreset == 2) {
x0 = 0.36295341867850555;
y0 = -0.6455617463848476;
} else if (centerPreset == 3) {
x0 = 0.3218759918211005;
y0 = 0.03518083572368085;
} else if (centerPreset == 4) {
x0 = -1.673497088962531;
y0 = -0.0003318667941149705;
}

float zoom = exp(zoomMajor + zoomMinor);
float x1 = x0 - 2.0 / zoom; // Left limit of x
float x2 = x0 + 2.0 / zoom; // Right limit of x

float spanX = x2 - x1;
float spanY = spanX * (float(size.y) / float(size.x));
float y1 = y0 - spanY / 2.0;
float y2 = y0 + spanY / 2.0;

x1 += centerOffset.x * spanX; // Shift centre for fine tuning of position
y1 += centerOffset.y * spanY;

float2 z = float2(x1, y1) + outCoord() * float2(spanX / float(size.x), spanY / float(size.y));
float2 z0 = z;
int n = 0;

dst = pixel4(0.0, 0.0, 0.0, 1.0); // Set everything to black first

/**
* Mandelbrot formula
* z' = z^2 + c
* where: z = a + bi
* z^2 = (a^2 - b^2) + (2ab)i
* and: c = x + yi
*/
while (n < maxIterations) {
aa = z.x * z.x;
bb = z.y * z.y;

if (aa + bb > BAILOUT) {
// Fill the pixel based on the time it takes to reach the bailout threshold
p = pixel4(1.0 - float(n) / float(maxIterations));
p.a = 1.0;
dst = p;
break;
}

twoab = 2.0 * z.x * z.y;
z.x = aa - bb + z0.x;
z.y = twoab + z0.y;
n += 1;
}
}
}

Tags: Fractals, Pixel Bender, Recursive   Last updated: 14 November 2008

5 Comments

  • Kevin Goldsmith commented at 14 November 2008 at 17:56

    sweet!

    You forgot to paste in the language version in your code:
    need to have

    <languageVersion: 1.0;>

    at the top

  • Tom commented at 14 November 2008 at 19:25

    Cheers Kevin :)

  • dragonfly commented at 15 February 2009 at 11:04

    Great visualizations of the Mandelbrot set!

    I also played with fractals in Pixel Bender -- it's really awesome! The speed is fascinating! And the code is pretty simple and straightforward.
    You can see my version of Pixel Bender fractal renderer at http://octets.ru/programmirovanie/flash-texnologii/pixel-bender-bystraya-otrisovka-mnozhestv-mandelbrota-i-zhyulia/
    I tried to make fractal coloring "non-conventional" ;)

  • Symbol commented at 7 March 2009 at 10:41

    Btw, do you know some good AS3 tutorial site? I'm normal with AS2 but practically don't get a thing in this new actionscript.. :(

  • Tom commented at 7 March 2009 at 22:43

    Symbol, I would highly recommend Colin Moock's book Essential Actionscript 3.0 from O'Reilly. After that Google is your friend ;-)

Post a comment

  • Required
  • Required, but will stay hidden
  • Optional
  • HTML tags <strong> and <em> are allowed.
  • Submitting...