Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Code Snippets / 3D Perlin Noise Generator and Demo (DBP)

Author
Message
Avan Madisen
22
Years of Service
User Offline
Joined: 12th Sep 2002
Location: The Castle Anthrax
Posted: 2nd Jan 2006 23:47
Hello programming addicts, game enthusiasts and fellow insane people

I've done a lot of playing around with procedural generation. Originally I started with fractals but because of the huge amounts of memory required to generate them and the fact you have to generate the whole thing in order to do anything with it, I never went very far. To be honest fractals are only good for small textures of landscapes (unless you've got a huge amount of memory to play with) and they would be useless for volumetric textures! I wanted something a little more usable.

I did, however, find a different method of generating procedural data called Perlin Noise, named after Ken Perlin who developed the technique back in the early 80's.

The process works in a similar way to fractals by calculating many different layers of random data and blending them together, but it works one position or set of co-ordinates at a time. It is slower then fractals but it's a lot more efficient since you can work out a small section of an image just as easily as a massive section. Plus there's no need to put the results through a series of filters, like fractals often require.

Ok, I'm first going to show you a demo program using the function I've created and then detail how to use the function yourself. (aren't I kind?)

One thing I neglected to remove from it was the multi-sampling, basically anti-aliasing, don't worry it's not important it's just a little fiddle to remove and this is only a demo, the multi-sampling isn't a part of the perlin function.

Anyway, what this program does it use the perlin noise function to generate a sphere-wrap texture to simulate landscapes and oceans, so when it's wrapped around a sphere you can't see the poles (the top and bottom caps). If you're feeling adventurous you could figure out how it does it. But basically it takes the co-ordinate of the texture and works out where on the surface of a sphere they would be in 3d space and then uses those co-ordinates to get a number from the perlin noise.

Think of it like grapping the colour of marble stone fro within the structure without having to carve you're way in.

It uses this like a height-map across the sphere to work out what areas are high and low, blah blah blah..

Once the texture is rendered it wraps it around a normal DBP sphere but made out of 32 rows and 64 columns. Just to show it if you hold the spacebar with the sphere is rotating you'll see it in wireframe.

One thing to remember also is if the program lots up for any reason or it's taking too long to draw the image press the spacebar and it should quit out.

WARNING: Before you run this program be aware that it uses a non-square image (1024/512) so older gfx cards may not like it. Also I'm running a 2ghz cpu here and it takes about 15-20 seconds to draw the image, so be patient if you're cpu is slower then mine.

Ok, just open the following code snippet, copy & paste it into DBP and run it:



Right that's that, now to show you all the important stuff. One thing to remember is there are a number of functions here, so I'll explain all of them, where they're needed and what they're for, that way you can use this stuff in your programs.

First of all you need to include a couple of lines at the beginning of your program:



Basically the first array is the octave data for the noise generator, think o the number of octaves as the number of layers in to the noise, I'll explain it later on.

The second one is the pre-calculated random data. Unfortunately I couldn't get the program to throw out the random numbers on the fly, for some reason the numbers weren't random, but this method is faster anyway and it doesn't up much memory, so don't worry.

Now I'll detail the first function you need:



This function does what it says on the name, it prepares the arrays detailed above for the Perlin function. If you don't use this function then you won't get much from the Perlin function. You only need to use this function once, however if you want to re-seed the noise then use it again.

Anyway, you need to provide this function with 2 parametres, the first being the seed, you'll notice the use of the 'randomize' command early on.

The second perametre is the persistance of the noise, in basic terms think of it as the roughness of the noise. If you mapped the results of the noise across an image then a low persistance would result in a very smooth texture, while a high persistance would create something a little more random. Most people still with 0.5 or there-abouts, if you set the persistance higher then 1 or negative you'll get some wierd and most likely useless results.

Next I'll go through the 'other' functions, the ones used by the Perlin function itself:



Don't worry about what these do, just include them with the Perlin function, otherwise it won't work.

Finally, the actual Perlin function itself, this is where all the work is done:



I know, it's not much code (I could possibly enter this into the 20 liner section), anyway, to get this function to work there are 4 perametres:

x#,y# and z# are the 3d co-ordinates within the noise you want to get the value of. Just like sampling a normal texture in 2d this is like sampling a texture in 3d. Give it the co-ordinates and it returns a value for you.

The final perametre is 'octaves' (mentioned earlier), this tells the generator how many octaves or layers you want. In a way this controls how detailed the noise is, the higher the octaves the more layers are processed. When mapped as a texture this produces more fine detail, however it can easily go a hell of a lot further then you could draw. I've already tested the system at 16 octaves on the program above, and it could've (with several gb of ram) rendered the same image at bigger then 65536/32786 and it would still be giving highly detailed shore-lines! Increasing the octaves will slow the whole process done. These numbers count from 1, so you literally input the number of octaves you want.

Ok, before you go and try to use this function yourself, let me explain a few key things.

The most important thing you need to know about the function is it returns a floating point value between 0 and 1. The demo program above multiplies this by 255 and then turns it into an integer so it can be used for a colour. Rememeber this trying to manipulate the result.

This function works just like sampling a texture, so to get an image you need to sample a lot of points within the noise and map the results into an image. This is why the system is so slow (or can be), it needs to do a lot of processing to get the result for just one point.

I would advise to keeping your sample area quite small, this is because the co-ordinates used to sample do cover a lot of the noise. I don't know exactly how to explain it, but if you play with the function you'll get the hang of it.

It's also a good idea to keep all you're sample co-ordinates positive, the function will accept any 3d co-ordinates, but if you start going negative some wierd things may appear.

Also try to keep the sample area near to the origin (co-ordinates 0,0,0) this will help to make sure the results don't get degraded by the inaccuracies of floating point variables.

I can't think of anything else, and before I even high the post button I know this is a very long post! I dread to think what spelling mistakes I've missed!

Ok, to finish this is the result of several months worth of little bits of programming, one or two hours every now and then, several re-writes of the code, one or two migraines (real migraines, not just bad headaches!) and a lot of playing around with the results this function can produce.

If anyone (possibly wishful thinking) can find a use for this, I'd appreciate a mention in the credits, and it'd probably be a good idea to mention the use of Ken Perlin's Noise as well.

Enjoy!

Don't look at me like that!
You're just jealous because the voices are talking to me!
Xenocythe
19
Years of Service
User Offline
Joined: 26th May 2005
Location: You Essay.
Posted: 3rd Jan 2006 00:09
Dang!!! Thats nice!!! AMAZING!!! WOOOT! YOU ROCK!
Phaelax
DBPro Master
21
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 3rd Jan 2006 23:06
I've tried playing with perlin before. I somewhat got it. Have you tried doing any type of cloud animation? It'd be too slow for any real-time needs, but it'd still look neat.


Deadly Night Assassins
Avan Madisen
22
Years of Service
User Offline
Joined: 12th Sep 2002
Location: The Castle Anthrax
Posted: 3rd Jan 2006 23:16
Far too slow for real-time, but it's perfectly possible, remember I built that function to be useful rather then just a show off.

Don't look at me like that!
You're just jealous because the voices are talking to me!
Ne0
18
Years of Service
User Offline
Joined: 6th Dec 2005
Location:
Posted: 4th Jan 2006 01:20
wow!!! THATS FREAKING AWESOME!!!



Some people know me as:
Cash Curtis II
19
Years of Service
User Offline
Joined: 8th Apr 2005
Location: Corpus Christi Texas
Posted: 5th Jan 2006 17:24
Very nice. Sorry that I ever doubted.

Login to post a reply

Server time is: 2024-11-23 07:22:25
Your offset time is: 2024-11-23 07:22:25