# 3D Perlin Noise

This topic is 4848 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Im trying to create 3D perlin noise using the improved Perlin Noise found here but using time as the third parameter. Ive tried converting his source code into C++ but all im getting is black and white noise. Do the inputs into the noise funtion have to have a value to the decimal part of them i.e. not 1.0, 2.0, 3.0 but for example 1.3, 2.63. I think I read somewhere that if they are whole numbers then it wont produce anything? In which case should I divide the x and y values from the loops by some factor? Hope you can understand what I mean. my source code is as follows:
int *p;

int permutation[] = { 151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
};

int main()
{
p = new int[512];
for (int i=0; i < 256 ; i++) p[256+i] = p = permutation;

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(NPIXELS, NPIXELS);
glutInitWindowPosition(100, 100);
glutCreateWindow("Perlin Noise");
glutKeyboardFunc(Keyboard);
glClearColor(1.0, 1.0, 1.0, 1.0);
gluOrtho2D(0, NPIXELS, 0, NPIXELS);
glutDisplayFunc(display);
glutMainLoop();
}

void display(void)
{
int x,y;
float pnoise, time;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f (0.0, 0.4, 0.0);
glPointSize((float)1);

glBegin(GL_POINTS);
for(x = 0; x <= 256; x++)
{
for(y = 0; y<= 256; y++)
{
time=0.5;
pnoise = noise(x, y, time) ;

glColor3f(pnoise, pnoise, pnoise);
glVertex2i(x, y);
}
}
glEnd();

glutSwapBuffers();
glFlush();
}

double noise(double x, double y, double z)
{
int X = (int)floor(x) & 255,                  // FIND UNIT CUBE THAT
Y = (int)floor(y) & 255,                  // CONTAINS POINT.
Z = (int)floor(z) & 255;
x -= floor(x);                                // FIND RELATIVE X,Y,Z
y -= floor(y);                                // OF POINT IN CUBE.
z -= floor(z);
double u = fade(x),                                // COMPUTE FADE CURVES
v = fade(y),                                // FOR EACH OF X,Y,Z.
int A = p[X  ]+Y, AA = p[A]+Z, AB = p[A+1]+Z,      // HASH COORDINATES OF
B = p[X+1]+Y, BA = p+Z, BB = p[B+1]+Z;      // THE 8 CUBE CORNERS,

return lerp(w, lerp(v, lerp(u, grad(p[AA  ], x  , y  , z   ),  // AND ADD
grad(p[BA  ], x-1, y  , z   )), // BLENDED
lerp(u, grad(p[AB  ], x  , y-1, z   ),  // RESULTS
grad(p[BB  ], x-1, y-1, z   ))),// FROM  8
lerp(v, lerp(u, grad(p[AA+1], x  , y  , z-1 ),  // CORNERS
grad(p[BA+1], x-1, y  , z-1 )), // OF CUBE
lerp(u, grad(p[AB+1], x  , y-1, z-1 ),
grad(p[BB+1], x-1, y-1, z-1 ))));
}

{
return t * t * t * (t * (t * 6 - 15) + 10);
}

double lerp(double t, double a, double b)
{
return a + t * (b - a);
}

double grad(int hash, double x, double y, double z)
{
int h = hash & 15;                      // CONVERT LO 4 BITS OF HASH CODE
double u = h<8 ? x : y,                 // INTO 12 GRADIENT DIRECTIONS.
v = h<4 ? y : h==12||h==14 ? x : z;
return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v);
}


Does this look ok? Ive just set time to a constant for the moment while I get it working. Thanks.

##### Share on other sites
Quote:
 Original post by Paul7Im trying to create 3D perlin noise using the improved Perlin Noise found here but using time as the third parameter....Do the inputs into the noise funtion have to have a value to the decimal part of them i.e. not 1.0, 2.0, 3.0 but for example 1.3, 2.63. I think I read somewhere that if they are whole numbers then it wont produce anything? In which case should I divide the x and y values from the loops by some factor? Hope you can understand what I mean.

I used this code as base for my own perlin noise and it wokrs just fine. I do similar as you but I scale inputs in 0..1 range.
( pnoise = noise(x/255.0f, y/255.0f, time); )

##### Share on other sites
Thanks thats improved it but getting this now:

Any thoughts why?

Also is there any way to alter the persistance, frequency and number of octaves with this code or are they encoded into it giving a fixed result based on all the numbers in the permutation array?

##### Share on other sites
Your code actualy calculates just one octave of perlin noise. You have to add them together with different amplitudes and frequencys to make it look good. There is not much you can do by chnaging this code.

// get 3D noisefloat CBFM::Noise( float x, float y, float z ) {  	float result = 0.0f;	for ( unsigned int i=0; i<octaves; ++i ) {		result += perlinNoise.Noise( x, y, z ) * amplitudeLUT[ i ];		x *= lacunarity;		y *= lacunarity;		z *= lacunarity;	}	return result;}

##### Share on other sites
Thanks alot Darkwing think ive got it sorted now.

##### Share on other sites
Right so Ive now got my perlin noise working so it animates dependant upon time. Im wanting to use this for water simulation and its too slow to calculate it every frame.

It was suggested to me before to generate a set of samples and interpolate between them. This needs to be made tileable so I can loop the playback of the samples. Any suggestions on how I go about doing this?

Thanks.

##### Share on other sites
Thanks that works great.

Just one more question. When using this as a heightmap for my water can I also use it to calculate the normals and then intepolate these between the samples also?

##### Share on other sites
Quote:
 Original post by Paul7When using this as a heightmap for my water can I also use it to calculate the normals and then intepolate these between the samples also?

Yes, but you'll probably have to renormalize them. Preferebly at perpixel level. It's not a problem if you use fragment programs / pixel shaders.

##### Share on other sites
yeah im using pixel shaders so thats not a problem. Thanks alot!

##### Share on other sites
Im having difficulty in getting this to look good for my water movement. I know its not the best method to use for water but should give reasonable results.

For the Perlin noise does anyone have any recommended values for the frequency, amplitude, etc.? and how many octaves would you recomend using?

When interpolating samples, how many samples should I use. At the moment I am only doing 10 and sampling it every second for ten seconds. I think this should be sampled more frequently but then I will end up with loads of samples increasing the memory requirements.

Any suggestions?

Thanks

##### Share on other sites
Quote:
 Original post by Paul7For the Perlin noise does anyone have any recommended values for the frequency, amplitude, etc.? and how many octaves would you recomend using?

For that you have to try yourself. Make your system so you can change those values at runtime and watch the results. You might also want to use modified perlin noise (turbolence, sin/cos noise,...).