• 13
• 18
• 19
• 27
• 10

# Improved Perlin Noise

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

## Recommended Posts

I'm in the process of implementing a 2D version of the Improved Perlin Noise, which I've completed for the most part. However I'm having trouble understanding the concept behind the generation of hashed gradient indices from the permutation values, and the code that chooses the actual gradients (which in turn is used to find the noise contribution at each corner of the grid cell). My basic understanding is that the permutation table essentially scrambles the gradient vectors in a predictable way. Looking at some presentation slides by Perlin, the gradient at [X,Y,Z] (i.e.. at a grid cell coord) is obtained via G[ p[p[p[X]+Y]+Z] ] (assuming indexing pointers wrap around the p[] bounds). Looking at the Improved Noise code, is there an underlying reason why the permutation tables are invoked in a manner shown below?

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,

What is the relationship between a particular permutation and the gradient hash bits? E.g.. Is there a specific reason to choose, say, bit 3 for determining the u value below? I'd appreciate if someone could shed some light on this.
  static 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);
}

I found another piece of code that reproduces the behaviour above, but still doesn't explain the hashing mechanism:
static float g3[16][3] =
{
{ 1, 1, 0},{-1, 1, 0},{ 1,-1, 0},{-1,-1, 0}, // center of cube to edges
{ 1, 0, 1},{-1, 0, 1},{ 1, 0,-1},{-1, 0,-1},
{ 0, 1, 1},{ 0,-1, 1},{ 0, 1,-1},{ 0,-1,-1},
{ 1, 1, 0},{-1, 1, 0},{ 0,-1, 1},{ 0,-1,-1}  // tetrahedron
};
int h = hash & 0xf;
return x * g3[h][0] + y * g3[h][1] + z * g3[h][2];

Perlin's Improved Noise implementation is here: http://mrl.nyu.edu/~perlin/noise/