0
176 Nov 09, 2008 at 04:25

Just thought I’d bring up the interesting subject of fractals and procedurally generated content. Over the past two weeks I’ve been doing some work on various fractals and iterated function systems. I didn’t know what to expect at first, but having gotten my feet wet I’m surprised at how simple these systems are. In some ways, I’ve always been interested in fractals since I heard about fractal landscapes and procedural generation of textures (see Terragen). I suppose too that since I’ve played Spore my interest in the subject has been vastly rejuvenated. Proof that there is a strong future for those systems. And with the ever-expanding multi-core computers, it’s a blast just watching how fast these things can be produced now.

So far I’ve dabbled around with mandelbrot, fractal flames, and the use of perlin noise and plasma clouds. The most difficult challenge actually is colouring the output. So many ways, but finding the nicest requires a bit of trial and error. This leads to my next goal, which is to improve on my colouring scheme. To make better use of noise and colours for textures. As a test, I’m aiming to produce something like Tarragen. See how far I can get with high quality textures and bring my GPU down to its knees ;)

A couple shots of my system so far.

As a fun side project, I’ve been rendering a couple 1080p mandelbrot videos too. Aside from being nauseous, it’s quite a trip.

Anyone else have experiences to share?

13 Replies

0
101 Nov 10, 2008 at 23:04

Not really my own experience, but you can’t talk about procedurally generated terrain without mentioning Infinity:

0
176 Nov 11, 2008 at 04:05

Whoa, impressive. I’m totally inspired. Just the fact that you see a Saturn like planet from the ground, knowing full well that if you left the planet’s orbit you could fly over to that planet. Jesus, and one man too. This guy is an animal. The graphics are just tack sharp.

Alright, no sleep for the next week ;)

0
101 Nov 11, 2008 at 09:35

And it is real-time (where terragen isn’t). You might want to take a look on his journal too.

Regarding “classic” fractals: the buddhabrot is one of my favourites: http://www.steckles.com/buddha/ or here: http://www.superliminal.com/fractals/bbrot/bbrot.htm . And the 4d Julia’s are cool too :)

0
101 Nov 11, 2008 at 18:47

@TheNut

Anyone else have experiences to share?

I wrote a few fracta renderers. The first one was written in VB, and rendered a Dragon or Koch kurve.

The second one was also VB, but drew a mandelbrot. I did it mostly because I got bored in a VB class in school.

The third one I wrote in C with OpenGL for rendering large “empty” areas as simple interpolated gradients. (I think I just checked if each corner of the quad differed from the others more than some low threshold, and recursively split the quad.) It was slow, even with all that OpenGL “acceleration”.

The fourth was plain C, pixel, by pixel. Worked well, but not very quickly.

There should be immense possibilities to optimize something like this. Some SSE and threaded rendering so our dual quadcores have some work to do for once?

How about yourself? Can you tell us anything on the technical side? rendering high-res fractal videos sounds time consuming…

0
101 Nov 11, 2008 at 21:03

@roel

And the 4d Julia’s are cool too ;)

As the nerd that I am, I have a 4d julia on my ATM card :happy:

(Here in the Netherlands a certain bank provides the service that you can put your own picture on the card)

0
176 Nov 11, 2008 at 23:34

I looked over his journal the other day and it was quite informative. I’m surprised how things are really that easy. He also got me thinking about Voronoi diagrams, which I completely forgot about. Very cool stuff that I’m working on implementing.

The buddhabrot is interesting. The nebulabrot (lol, who comes up with these names) makes me think of space invaders. I’ve seen some YouTube videos where they’ve animated the colours, but if it’s possible to slightly animate the shape (slight rotations and what not), it would make for an interesting addition to my video.

The video itself is quite time consuming. I’m rendering it on a dual core 1.8GHz. Some scenes take 2-3 days of processing to film the full zoom on one section at roughly 2048 max iterations (though it varies on what I’m targeting). And if I make a mistake, I smash myself into the wall head first.. To make things worse, I’m producing the videos at 60fps and downsampling the output images from 3840x2160 to 1920x1080. It’s really worth it though. I wrote the thing in C++ so there’s no fancy assembly going on (see QuickMAN), but I am taking advantage of multithreading. I’m even contemplating adding a network renderer to get my other PCs to join in. Hmm, I should also get the GPU to help out too. Heh, the funny thing is my PC can’t even playback the final video. 60fps HD is to much for my crummy PC to handle.

The fractal flame algorithm is a lot worse too since it requires tons of iterations to converge the result. I’d love to do videos with that because it’s so fluidic and beautiful, but it would take a month just to do a 1 minute video.

I have a 4d julia on my ATM card

Better to have julia than starfleet’s logo on there ;)

0
102 Nov 12, 2008 at 21:11

very nice!

0
176 Nov 14, 2008 at 05:08

So I decided to port my Mandelbrot renderer over into a fragment shader and… WHOA! Talk about insane speed. It doesn’t have the precision or quality I get on the CPU, but just to navigate around is incredible. Because it’s the week of the Mandelbrot, I’ll post my shader code if anyone is interested in trying it out themselves or wants to improve their overall shader knowledge. I’ll also post my fractal test app I’ve been working on soon. It generates some pretty nice desktop wallpaper. Every day is a new image ;)

CPU quality is obviously better, but GPU kicks my Intel’s butt in speed.

Feel free to use the shader code below however you see fit. You could trim it down some more given that your application would be different than mine.

/*
Author:     Nathaniel Meyer
E-Mail:     nate@nutty.ca
Website:    http://www.nutty.ca

Desc:       Fragment program for calculating and drawing
the mandelbrot on a shape's surface.
*/

// Textures
// tex0 is used to render to texture by the CPU
// if shaders are disabled. tex1 identifies the
// gradient texture used to colour the mandelbrot.
uniform sampler2D tex0;
uniform sampler2D tex1;

// Variables to be provided by application
// maxIteration     - A finite "infinity" number to prevent the
//          calculation loop from going on forever.
// real         - Starting x-coordinate in mandelbrot.
// imaginary        - Starting y-coordinate in mandelbrot.
// scaleX       - Maintain aspect ratio: 3.0 / window_width.
// scaleY       - Maintain aspect ratio: 2.0 / window_height.
uniform int maxIteration;
uniform float real;
uniform float imaginary;
uniform float scaleX;
uniform float scaleY;

// Keep track of complex number system.
float z;
float cfX;
float cfY;
float fX;
float fY;

/*
Calculate mandelbrot
*/
int mandelbrot (int numIteration)
{
int iteration = 0;
float temp;

// Zn+1 = Zn^2 + c
while ( ((z = ((cfX*cfX + cfY*cfY))) <= (4.0)) && (iteration < numIteration) )
{
temp = cfX*cfX - cfY*cfY + fX;
cfY = 2.0*cfX*cfY + fY;
cfX = temp;

++iteration;
}

return iteration;
}

/*
*/
void main ()
{
// Start location
fX = real + ((gl_TexCoord[0].s - 0.5) * scaleX);
fY = imaginary + ((gl_TexCoord[0].t - 0.5) * scaleY);

// Calculate mandelbrot
int iteration = mandelbrot(maxIteration);

// Process result
if ( iteration == maxIteration )
{
// Not part of the mandelbrot solution
gl_FragColor.xyz = 0;
}
else
{
float intensity;

// Faster, but subject to colour banding
//intensity = float(iteration) / float(maxIteration);

// Normalized Iteration Count.
// Slower, but reduces colour banding
// Smoothing. Add a few extra counts to reduce error
iteration += mandelbrot(1);
z = (cfX*cfX + cfY*cfY);
intensity = (float(iteration) - (log(log(sqrt(z))) / log(2.0))) / float(maxIteration);

// If a texture gradient is not provided, this formula
// will render a standard greyscale mandelbrot.
//gl_FragColor.xyz = intensity;

// Provide a 1D gradient for the mandelbrot to render
// colours. It should be of sufficient width (1024 pixels)
gl_FragColor.xyz = texture2D(tex1, vec2(intensity, 0)).xyz * 2.0;
}

// Set final output
gl_FragColor.w = 1.0;
}

0
101 Nov 14, 2008 at 22:06

I’m looking forward for your app!

0
176 Nov 15, 2008 at 05:51

Here you go. I included links to download the program for either Windows or Linux. I had to spend some time brushing up the interface, but it should be good enough to get around. Instructions are included in the readme.txt file. You’ll find all the mouse and keyboard controls in there, as well as how to add your own gradients. One thing I didn’t mention is that you can edit resources/gui.xml and add your own resolutions and max iterations (if you really want to go psycho on your computer). Also, you can’t take screenshots while in Shader mode. I was to lazy to get the frame buffer and setup all that jazz ;)

0
101 Nov 15, 2008 at 11:19

I had (Fractal) Fun indeed :) Too bad that my videocard doesn’t do GLSL though.

0
176 Nov 15, 2008 at 16:02

What video card do you have? My netbook has an Intel 945GME that supports shader model 2.0, but not GLSL. I’m thinking about returning back to Cg to get that added support. I’m sure even on that Intel chip rendering via the GPU would show a great deal of added performance.

0
101 Nov 16, 2008 at 21:54

I have a Radeon 9600 All In Wonder :) And yes, it also supports sm 2.0.