Page 1 of 1

## Perlin Noise A simple explanation on Perlin Noise. Rate Topic: //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'http://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=66480&amp;s=1b14cb87a372a8ffd6f9db9a8da10776&md5check=' + ipb.vars['secure_hash'], cur_rating: 0, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

### #1 Pontus

• Cattlebruiser

Reputation: 18
• Posts: 612
• Joined: 28-December 06

Posted 06 October 2008 - 01:20 PM

Hi there, guys

I'm here to teach you something about Perlin Noise. You know, that magical thing that gives infinite possibilties and is usefull in every single game.

To be honest with you, it's not that very difficult, but it can be if it's not explained right.

First, the theoratical side:

Now, what exactly is perlin noise? Well, it is some pseudo random coherent noise. Let me explain that bit by bit:
*Pseudo random: This means that it appears random, but you get the same result twice every time you call it. Think of the rand() function. You might have
noticed that if you not seed it it always will give number 13 as first. If it was to be fully random you would get a different number everytime.

*Coherent: This means that it is very smooth. Here's a picture of some non-coherent noise.

This is coherent noise

Imagine that you zoom in on that non-coherent noise, and as you zoom in, you see that there are transitions between those pixels, and there you go,
coherent noise!

But that contrast is a bit high, don't you, let's smooth it out a bit:

There we go, looks much better, doesn't it?

But if you want to use it as a heightmap, it will be a bit too smooth, don't you think? Well, let me show you how to improve that by using octaves.
Maybe this image will help explain:

So, the smoothed noise is image a. If We zoom out on that noise, we get image b, and if we zoom out on b, u get image c. If u add a,b,c,... U get this:

And this is what we are going for.

Now, lets take that what we have learned and bring it in the practical side.

First of all, we'll need a pseudo-random number generator:

I searched a bit on the web and I came across this one:

1D
```inline double findnoise(double x)
{
int x = (x<<13) ^ x;
return (double)( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & Ox7fffffff) / 1073741824.0);
}

```

Here's the 2D version
```inline double findnoise2(double x,double y)
{
int n=(int)x+(int)y*57;
n=(n<<13)^n;
int nn=(n*(n*n*60493+19990303)+1376312589)&0x7fffffff;
return 1.0-((double)nn/1073741824.0);
}

```

Don't ask me how it works because I dont know how it works myself, something with prime numbers... But what I do know is that it returns a value between
-1 and 1, just like our perlin noise function.

Now, as I've explained before, we get coherent noise because we look between the pixels, so our perlin noise function must be able to accept
double numbers. So we have to interpolate between the pixels. Interpolate is like taking the average, but a little bit more complicated. We'll be using
cosine interpoliation. It gives a very nice effect because it looks like a curve. But I wont explain too much, that's maybe for another tutorial.
Here is it.

```inline double interpolate(double a,double b,double x)
{
double ft=x * 3.1415927;
double f=(1.0-cos(ft))* 0.5;
return a*(1.0-f)+b*f;
}

```

Now you might ask: "Hey, what about the 2D version?". Well, let me explain this. Let's take the average of a and b and call it d.
Let's also take c and d and call it e. And if we take the average of d and e it would equal to the average of a b c and d.
This enables us to stick to 1 dimension, making the code alot easier. Now, I'll combine these into one function. It uses SDL for image handling.

```double noise(double x,double y)
{
double floorx=(double)((int)x);//This is kinda a cheap way to floor a double integer.
double floory=(double)((int)y);
double s,t,u,v;//Integer declaration
s=findnoise2(floorx,floory);
t=findnoise2(floorx+1,floory);
u=findnoise2(floorx,floory+1);//Get the surrounding pixels to calculate the transition.
v=findnoise2(floorx+1,floory+1);
double int1=interpolate1(s,t,x-floorx);//Interpolate between the values.
double int2=interpolate1(u,v,x-floorx);//Here we use x-floorx, to get 1st dimension. Don't mind the x-floorx thingie, it's part of the cosine formula.
return interpolate1(int1,int2,y-floory);//Here we use y-floory, to get the 2nd dimension.
}

```

And there we are, a perlin noise function. It returns a value between -1 and 1. To convert this to a 0-256 RGB value, we simple multiply it by 128,
then add 128 to it. But in the theory section I mentioned something about octaves, well I'll show it now. I call this result clouds.

```SDL_Surface *Render_Clouds(int w,int h,double zoom,double p, int r, int g, int b)//w and h speak for themselves, zoom wel zoom in and out on it, I usually
{//										   use 75. P stands for persistence, this controls the roughness of the picture, i use 1/2
int octaves=2;
SDL_Surface *ret=SDL_CreateRGBSurface(SDL_SWSURFACE,w,h,24,0,0,0,0);//Create an empty image.
for(int y=0;y<h;y++)
{//Loops to loop trough all the pixels
for(int x=0;x<w;x++)
{
double getnoise =0;
for(int a=0;a<octaves-1;a++)//This loops trough the octaves.
{
double frequency = pow(2,a);//This increases the frequency with every loop of the octave.
double amplitude = pow(p,a);//This decreases the amplitude with every loop of the octave.
getnoise += noise2(((double)x)*frequency/zoom,((double)y)/zoom*frequency)*amplitude;//This uses our perlin noise functions. It calculates all our zoom and frequency and amplitude
}//											It gives a decimal value, you know, between the pixels. Like 4.2 or 5.1
int color= (int)((getnoise*128.0)+128.0);//Convert to 0-256 values.
if(color>255)
color=255;
if(color<0)
color=0;
SetPixel(ret,x,y,(int)((r/255.0)*(double)color),(int)((g/255.0)*(double)color),(int)((b/255.0)*(double)color));//This colours the image with the RGB values
}//														   given at the beginning in the function.
}
return ret;
}

```

And this gives some nice clouds. I hope you enjoyed this tutorial, and I there's enough request, I'll make a more in-depth sequel.

Is This A Good Question/Topic? 2

## Replies To: Perlin Noise

### #2 Deepglue555

Reputation: 7
• Posts: 118
• Joined: 13-April 09

Posted 18 May 2009 - 01:38 AM

how might i generate Guitar Tube Amplifier hiss/hum or change a transistor amp to sound like a Tube Amplifier for Guitar or better Stereo/Mp3 player lol

### #3 Pontus

• Cattlebruiser

Reputation: 18
• Posts: 612
• Joined: 28-December 06

Posted 18 May 2009 - 07:52 AM

I don't know anything of guitars. I think you'd be better of at a music forum.

### #4 Guest_Maito*

Reputation:

Posted 21 February 2010 - 06:29 PM

Hi.

I really like your tutorial, but I don't understand one thing of the code.
You tell us about the setPixel function but when I try to use it, compilers throws a message saying this function doesn't exists.
What is the problem with this? What function is it? Do I have to write the code of setPixel instead?

### #5 Guest_pontus*

Reputation:

Posted 22 February 2010 - 09:20 AM

Yes, you have to make one yourself. It's a function that sets a given color on a given pixel in the image. As It's a tutorial on just the perlin noise not all the basic functions are made.

### #6 doveraudio

Reputation: 1
• Posts: 23
• Joined: 17-March 10

Posted 17 March 2010 - 05:03 PM

thanks so much for this blurb. converted the interpolate function into a synthedit module, wondering if you'd mind if i share it with people. hoping for permission to credit you in the "liner notes"

(also hoping to use the rest of the code too - the interpolate bit really helped this stuff click)
```		ft=input1 * 3.1415927;
f=(1.0-cos(ft))*0.5;
float result = input2*(1.0-f)+input3*f;
```

hoping you make more tutorials, thanks for the function on too btw. cheers.

### #7 Pontus

• Cattlebruiser

Reputation: 18
• Posts: 612
• Joined: 28-December 06

Posted 18 March 2010 - 08:44 AM

doveraudio, on 18 March 2010 - 12:03 AM, said:

thanks so much for this blurb. converted the interpolate function into a synthedit module, wondering if you'd mind if i share it with people. hoping for permission to credit you in the "liner notes"

(also hoping to use the rest of the code too - the interpolate bit really helped this stuff click)
```		ft=input1 * 3.1415927;
f=(1.0-cos(ft))*0.5;
float result = input2*(1.0-f)+input3*f;
```

hoping you make more tutorials, thanks for the function on too btw. cheers.

You can spread this tutorial and the code as much as you like. Just include a link to this original topic.

### #8 doveraudio

Reputation: 1
• Posts: 23
• Joined: 17-March 10

Posted 20 March 2010 - 08:23 PM

Pontus, on 18 March 2010 - 07:44 AM, said:

doveraudio, on 18 March 2010 - 12:03 AM, said:

thanks so much for this blurb. converted the interpolate function into a synthedit module, wondering if you'd mind if i share it with people. hoping for permission to credit you in the "liner notes"

(also hoping to use the rest of the code too - the interpolate bit really helped this stuff click)
```		ft=input1 * 3.1415927;
f=(1.0-cos(ft))*0.5;
float result = input2*(1.0-f)+input3*f;
```

hoping you make more tutorials, thanks for the function on too btw. cheers.

You can spread this tutorial and the code as much as you like. Just include a link to this original topic.

cool 8)

### #9 doveraudio

Reputation: 1
• Posts: 23
• Joined: 17-March 10

Posted 20 March 2010 - 08:44 PM

Deepglue555, on 18 May 2009 - 12:38 AM, said:

how might i generate Guitar Tube Amplifier hiss/hum or change a transistor amp to sound like a Tube Amplifier for Guitar or better Stereo/Mp3 player lol

word. come over to http://www.kvraudio.com/.

if you're into coding, i could use some help at dovergadget on sourceforge. i use the synthedit sdk 2, i could email u a copy as it's no longer online.

By creating synthedit modules i get to work more with dsp ideas and less rhetorical stuff. not that i'm very good at this stuff yet at all.

This post has been edited by doveraudio: 20 March 2010 - 08:50 PM

### #10 iko79

Reputation: 0
• Posts: 1
• Joined: 24-April 12

Posted 24 April 2012 - 05:51 AM

You've got multiple used symbols in your explaination of bilinear interpolation.

Pontus, on 06 October 2008 - 01:20 PM, said:

Let's take the average of a and b and call it d.

Let's not, because it is already occupied by the fourth pixel in a, b, c, d.

Also, there is a typo in the code: you call "interpolate1" which is undefined.

Anyway, thanks for the code, you really saved me some time!

Cheers,
iko