Fun with Fractals


This week I decided to go over a short research essay I did for ‘Numerical Methods & Advanced Mathematical Modeling’ at Trinity College.
In it I go over fractals, their origin, use and so on, but I’ll spare you the boring details and go directly to the fun part, sticking it on the GPU (and on the 360), namely the Mandelbrot set.

Some history…

For those who don’t know, a fractal can be roughly described as “a fragmented geometric shape that can be split into parts, each of which is (at least approximately) a reduced-size copy of the whole”. This term was coined by Mandelbrot himself, who used them to study natural shapes, like in his paper “How Long is the Coast of Britain?” tackling the coastline paradox. In 1980, Mandelbrot defined the Mandelbrot set, a set of parameters for which a certain Julia set is connected. The Mandelbrot set is still one of the most popular fractals ever discovered.

The algorithm…

I’d like to start out by naming my sources. One of my first references for implementing the Mandelbrot on the GPU was Shawn Hargreaves (you can check his article here, great stuff). Another reference worth having a look was Linas Vepstas’ article on renormalizing the Mandelbrot escape (see here). Check the paper for further references.
So, how do we get the Mandelbrot on a shader in the first place? First let’s go over ways to approximate the Mandelbrot numerically. The most popular way of estimating and representing the Mandelbrot set is to use the escape time algorithm. The escape time algorithm calculates evaluates the connectivity of each set from the famous quadratic polynomial


on the plotted area by testing whether or not the orbit of its starting point tends towards infinity under iteration. To do this we test the values against an escape condition. If that condition is reached then the tested set is considered disconnected (its orbit tents towards infinity) and it’s disregarded from the set. If, on the other hand, the escape condition is never reached after a maximum number of iterations, it is assumed that its orbit does not tend towards infinity and it is thus included into the set.
There are different test conditions, but the most common condition (for its simplicity) bases itself on the fact that no complex number of ‘z = x + yi’ where ‘x > 2′ or ‘y > 2′ can be part of the set.
So now that we know how to estimate the set, let’s see how we can represent it using the escape time algorithm. One of the most common ways would be to assign a binary set of colours (usually black and white) depending on whether or not the point is considered part of the set. That’s not very exciting though, we want pretty pictures, with all the shiny colours, so instead we use the number of iterations (how fast a given set’s orbit tended towards infinity) as an index for our colouring from a colour map, this map can be defined by an artist to make it all ‘ooooh’.
Taking all the stuff we discussed above we can express an algorithm as such…


Where complex values z and c compose the above mentioned quadratic polynomial, e defines the escape radius and m defines the maximum number of iterations.

Complex numbers 101

That’s all very nice in paper but we can’t just write that down on our shader straight away, so for those without alot of background on complex numbers, let’s break them down to size.
A complex number is defined by two parts, real and imaginary. The usual notation for these numbers is ‘a + bi’ where a and b are real numbers and i represents the imaginary unit. We’re going to plot a certain area of the complex plane with the above algorithm. The complex plane is a two-dimensional Cartesian coordinate system where a complex number represents a point or vector on said plane.
Let’s look at some basic associative, commutative and distributive complex number operations to help us flesh out our final algorithm.

For a complex number z = a + bi and a second complex number
w = c + di we de fine the following operations…

  • Addition:
  • Multiplication:
    from this we can conclude…
  • Absolute value:


And this way we can get a shader friendly algorithm like the following…

Pretty colours…

This is great, but we can get even nicer results by getting rid of the step effects we got from using an integer value for mapping our colour values.
To solve this we use the renormalized escape time algorithm defined by Linas Vepstas where the colour index is defined by…


A great explanation of this is given by Earl L. Hinrichs (quoted from Linas Vepstas).
“Ignoring the +c in the usual formula, the orbit point grows by z = z^2. So we have the progression z, z^2, z^4, z^8, z^16, etc. Iteration counting amounts to assigning an integer to these values. Ignoring a multiplier, the log of this sequence is: 1, 2, 4, 8, 16. The log-log is 0, 1, 2, 3, 4 which matches the integer value from the iteration counting. So the appropriate generalization of the discrete iteration counting to a continuous function would be the double log.”.

The code…

Now its just a matter of converting the algorithm into code. One optimization that’s worth noting here is the use of a texture lookup as a colour map. This can make use of a wider range of colours than the ones available in the map itself through the graphics card’s filtering, which can be pretty much free. In my example I only make use of one dimension when applying the colour map, I left it at that for the sake of simplicity. Also, it would be extremely easy for an artist to edit the colour map applied to the fractal.

Shader Source Code

// Calculate initial point
float2 c = (texCoord - 0.5) * Zoom * float2(1, Aspect) - Pan;
float2 v = c;

// Check for connectivity
// Escape Time Method
// IF absolute of Z > Escape Radius
- Disconnected (Tending towards infinity)
// OR Iterations == Iteration Limit
- Connected (Orbit bounded, assumed to be not tending towards infinity)
int n = 0;
while( v.x*v.x + v.y*v.y <= EscapeRadiusSquared && n < Iterations )
{
       // Evaluate function: Fc(x) = z^2 + c
       v = float2(v.x * v.x - v.y * v.y, v.x * v.y * 2) + c;
       n++;
}

// IF disconnected, calculate color from number of iterations
float4 color = 0;
if(n < Iterations)
{
       // Renormalize interation count
       // a couple of extra iterations helps
       // decrease the size of the error term.
       v = float2(v.x * v.x - v.y * v.y, v.x * v.y * 2) + c; n++;
       v = float2(v.x * v.x - v.y * v.y, v.x * v.y * 2) + c; n++;
       float absolute = sqrt(v.x*v.x + v.y*v.y);
       float mu = n - log(log(absolute))/log(2); // double log (0,1,2,...)
       // Fetch color from color map (texture)
       // Bilinear filtering will increase number of possible colours for free!
       color = tex2D(TextureSampler, float2(fmod(mu,NumberOfColors)/NumberOfColors,0));
}
// Final plot result (coloured)
return color;


And there we go, a nice and pretty Mandelbrot shader running on real time on the GPU. The video below gives you a nice look at how it turns out, a beauty.

YouTube Preview Image

Hope you enjoyed this little article and I will be back soon with more stuff to show.
See ya!

Paper [Download]
Source Code [Download]

Still alive!

After a long period of inactivity, I’m finally updating the blog, bringing everything up to speed. It’s hard to overstate my satisfaction.
I apologize for the absence. After starting an MSc., moving to Ireland and many a Guinness, I finally found some time to post again.
For the next couple of days I’ll be posting what I’ve [...]

The Indie Bay Competition Winner

The competition is over and the winner is Midnight Ritual. Congrats to Tahir and anyone who participated on the competition. Despite the critics I can’t wait for the next one. Lots of fun!

The Indie Bay Competition

Duct tape, gum, and a pair of tweezers
If, like me, you love making games and have 48 hours to spare, check out the 48hour Indie Bay Competition over at theindiebay.com/competition kicking off later this month on the 19th.
Kudos to David from TheIndieBay.com and good luck to all the competitors!

Day 3 - GDC Europe, Köln 2009

R2D2 at Gamescom 2009The final day of GDC Europe finally came, and with it all the crazy chaos of the first day of Gamescom, just next door. I arrived and reported to my post to find out that the Gamescom organization had taken over one of the balconies and the entrance, sending all the staff to a single side. This caused us to have too many people for the posts available, so they ended up releasing us volunteers except for an occasional need to move something around or pack some printers.

Day 2 - GDC Europe, Köln 2009

Elevator entrance - GDC Europe, Köln 2009Like the day before, only a few hours after the party (even fewer that day 1), I was getting up for my first day of work. The streets were still empty and hardly anyone was on the trains. Reaching the conference only a few staff members were walking around in a hurry. I walked around the Expo Floor, looking at the still empty booths, took a few pictures and just wandered around biding my time. Soon I’d walk over to the show room where I’d change to my staff t-shirt and follow one of the staff down to the registration area to know what kind of work I was doing.

Day 1 - GDC Europe, Köln 2009

Intel Booth - GDC Europe, Köln 2009Just a few hours after the reception, I was waking up and heading to the Koelnmesse again. I didn’t work today so I wanted to make the most of my free day. Got to the conference through the elevator and wandered around the Exposition Floor, where many spent most of their time away from the sessions. To my left I could see the CCP booth, hiring some talent; to my right a few booths, mostly indie I think, the only name I recognized was ‘Tale of Tales’, though the guys from ‘Sakari Games’ had a really nice lego-like shooter in showcase. Moving on to the over side of the room I passed through the Autodesk booth, and at the end of the hall leading to a open-air social area I could see the Intel booth on my left, and the Crytek booth on my right.

GDC Europe, Köln 2009

Game Developers Conference Europe 2009A few months back I decided to try GDC again and got myself a place as a volunteer over at the European conference in Köln. So there I went, bags packed and leaving to Deutschland, hoping to have a good time, meet interesting people and drink great beer (which is pretty much what happened).

GDC, London 2006

I’m currently writing an article about my experience as a volunteer at the Game Developers Conference in Köln a few days ago. I’ll be posting it throughout the following days, each post describing one day at the conference. So just for the sake of completion I decided to translate my old article for GDIsep about a similar experience back in 2006. So, without further ado, here we go…

Game Developer’s Conference London 2006

One day (not sure which one) I decided to volunteer for the GDC London (unsure of what kind of answer I’d get). To my surprise, the answer was extremely positive, so there I went to London, bags packed and expectant of what would come. Throughout the following pages I’ll share my experiences at the Conference. What I heard in the sessions, highlights, points of interest, etc.
I apologize if I’m not completely clear, or for any reason wasn’t able to discuss something with further detail, but I wrote this article so people could have an idea of what went on, what was discussed. A peek at the conference through my eyes.

Back to the Basics: Scene Management

Hello and welcome to the first actual post on the ‘No More Coins‘ blog.

I’m using this post to document a new venture into XNA. I’m coding a new layer into XNA adding extra functionality to support my game programming needs. That and a set of tools I’ll hopefully get the chance to make sometime in the future are lovingly called the XNAlchemist Engine. This is based on another older project still WIP called The Alchemist, a basic multiplatform game engine in C++.
Ok, so besides the fundamental classes and wrappers the first hot topic to touch in development is, of course, Scene Management.
Not very exciting, I know! But even though its not all bells and whistles it’ll definitely pay off in the future. Good foundations and all that jazz…

From the many techniques for scene management, I decided two were crucial enough to implement at this stage: Octrees and Portals.