Fractal Lab started around the beginning of 2011 as my first explorations rendering fractals in the browser with WebGL. Previously I had created renderers using Adobe PixelBender and QuartzComposer, which both had the advantage of easy integration into Photoshop and AfterEffects but were very limited when it came to interactively exploring the fractal space.
Fractals are by nature highly detailed and so the smallest change to an input parameter can often result in dramatic differences in the output shape. In order to properly explore the space (and discover hidden gems that coalesce at specific parameter combinations) I decided to build a new UI (that had to nice to use!), a control system and a new GLSL renderer in WebGL to take advantage of the parallel computing power of the GPU in a web browser.
The first version of Fractal Lab was a proof of concept to show that you could modify and fly around the fractals in the browser at interactive speeds. It was also intended as a portfolio piece, which subsequently opened the doors for my current career path ;-)
Although I had dabbled with the idea of turned Fractal Lab into a full featured product it currently remains a personal side project that I hack around with in my free time to try new web technologies and rendering approaches. It also provides a way to satisfy my creative cravings, the results of which I've collected together on this site!
Now four iterations on, the version shown above is written in Coffeescript, and uses the micro MVC framework Spine along with a Gulp and Browserify based workflow. It also has a basic Ruby on Rails backend API for storing the scenes.
The technique Fractal Lab uses to render 3D fractals is called distance field ray marching (also known as sphere tracing). It's a technique that originally gained popularity in the demo scene and has since been extensively documented by Iñigo Quílez.
For the curious this article offers a very clear introduction followed by the excellent in-depth series of posts by Mikael Christensen.
There is also a wealth of algorithm details described by many talented people over at fractalforums.com, which is where all this started…
Be warned though, once you start down the graphics programming rabbit hole you might not be able to leave ;-)
Rendering fractals is very a computationally expensive process. A 2D fractal requires tens or hundreds of iterations for each pixel, a 3D fractal then repeats this process tens or hundreds of times as it ray marches into the scene. The GPU helps by processing many pixels in parallel, but even a top-end system will struggle or even fail to render a scene at full resolution. To maintain responsive interaction Fractal Lab uses a progressive rendering process which can be thought of as a grid interlacing technique.
A full resolution frame buffer acts as an accumulator but the rendering is done on a separate quarter size frame buffer. On the first pass this fills the accumulator giving a pixelated view. The subsequent passes only colour one pixel per block of four; second pass colours the top right, third pass the bottom left and the final pass the bottom right. This way you can immediately get a feel for the scene as everything has some level of coverage.
Using this approach many scenes have 30fps interaction speeds at around a 1280x720 accumulator size which continue to refine to a 4x super-sampled image in less than a second.
Super-sampling is very important, even in the interactive editor mode, as often the interesting details only appear once the jaggy edges have resolved.
Another performance optimisation used in the GLSL renderer is to avoid condition statements where possible. It is often more efficient for the GPU to perform calculations that are then discarded (via min/max/mix/step statements) than branch into different paths which are then limited to the slowest pixel in the batch being calculated.
Fractal Lab also has a shader pre-processor updated from the UI controls that will set #define statements before compiling so many boolean and global state options can be replaced with compile time #ifdef statements which allow large unused chunks of the shader to be bypassed.
From the browser to desktop
Since browsers run in a sand-boxed environment access to the local filesystem is restricted. To save rendered frames from the browser Fractal Lab uses the Dropbox API to upload the images, which then reappear after a few seconds in your local Dropbox folder. A rather roundabout method but works reliably.
Fractal Lab is my personal technical and creative canvas where I can explore ideas freely in my own time without obligations and support commitments, so for the moment it isn't available online or for local installation.
I have some project ideas I first want to fully explore using Fractal Lab, after that I'll probably release the code.
However, for those itching for more right away there are other well established apps for exploring 3D fractals and interactive raymarching:
- Fragmentarium is a cross platform desktop app created by Mikael Christensen (mentioned earlier). It lets you write and edit GLSL fragment shaders and builds a basic UI to control the parameter inputs.
- Mandelbulb3D a Windows based app with a huge number of formula options and features. It doesn't use the GPU and so is much slower to render but doesn't have the floating point single precision limit of the GPU renderers, which means you can zoom in much deeper.
- Mandelbulber another cross platform desktop app. Not as popular as Mandelbulb3D but possibly easier to get started with.
- Synthclipse a relatively new app which uses the Eclipse editor framework to create a GLSL shader development environment similar to Fragmentarium. It also has the ability to import existing shaders from external sources like ShaderToy.
- ShaderToy a WebGL sandbox for created GLSL fragment shaders to explore ray marching, fractals and other GPU generative graphics in the browser. Written by Iñigo Quílez (also mentioned earlier) it has some excellent demos from many very experienced graphics programmers.
Many more are popping up over at fractalforums.com so get involved there too!