procedural generation - How do the permutation and gradient tables of Perlin and Simplex Noise work in practice? -


so have been doing bit of research how perlin , simplex noise work and, while core principles of regular perlin noise i'm little bit confused how permutation , gradient tables work.

from understanding, provide better performance seeded random number generator tables of pre-computed values nicely indexed quick access.

what don't entirely though how work practically. i've seen permutation table implemented array of shuffled values 0-255 so:

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 }; 

but i'm unsure practial purpose of this. want know is:

  • how permutation table used in relation grid points?
  • how gradient table generated?
  • how values permutation table used gradient table? permutation values correspond indices gradient table?

i've been taking libnoise , perlin noise code apart off , on while understand how worked. hate working code don't understand :)

walking through http://catlikecoding.com/unity/tutorials/noise/ may if don't use unity, might able convert code accordingly. helped me alot.

there various other sites out there hints , tips. google libnoise, procedural, etc should show examples can through.

basically though gradients used in noise in conjunction integer array points around 0,0,0 few pad out set number. using combination of integer number picked based on x,y,z coordinate (0 , 1 indicating each side of point ) example such have:

// separate integer element int ix0 = int(point.x); int iy0 = int(point.y); int iz0 = int(point.z);  // grab fractional parts use later float tx0 = point.x - ix0; float ty0 = point.y - iy0; float tz0 = point.z - iz0; float tx1 = tx0 - 1f; float ty1 = ty0 - 1f; float tz1 = tz0 - 1f;  // make sure value compatible integer array ix0 &= hashmask; iy0 &= hashmask; iz0 &= hashmask;  // other side of point int ix1 = ix0 + 1; int iy1 = iy0 + 1; int iz1 = iz0 + 1;  // grab integers found @ location in array int h0 = hash[ix0]; int h1 = hash[ix1]; int h00 = hash[h0 + iy0]; int h10 = hash[h1 + iy0]; int h01 = hash[h0 + iy1]; int h11 = hash[h1 + iy1];  // gradient array private static vector3[] gradients3d = {     new vector3( 1f, 1f, 0f),     new vector3(-1f, 1f, 0f),     new vector3( 1f,-1f, 0f),     new vector3(-1f,-1f, 0f),     new vector3( 1f, 0f, 1f),     new vector3(-1f, 0f, 1f),     new vector3( 1f, 0f,-1f),     new vector3(-1f, 0f,-1f),     new vector3( 0f, 1f, 1f),     new vector3( 0f,-1f, 1f),     new vector3( 0f, 1f,-1f),     new vector3( 0f,-1f,-1f),      new vector3( 1f, 1f, 0f),     new vector3(-1f, 1f, 0f),     new vector3( 0f,-1f, 1f),     new vector3( 0f,-1f,-1f) };  private const int gradientsmask3d = 15;  // grab gradient value @ requested point vector3 g000 = gradients3d[hash[h00 + iz0] & gradientsmask3d]; vector3 g100 = gradients3d[hash[h10 + iz0] & gradientsmask3d]; vector3 g010 = gradients3d[hash[h01 + iz0] & gradientsmask3d]; vector3 g110 = gradients3d[hash[h11 + iz0] & gradientsmask3d]; vector3 g001 = gradients3d[hash[h00 + iz1] & gradientsmask3d]; vector3 g101 = gradients3d[hash[h10 + iz1] & gradientsmask3d]; vector3 g011 = gradients3d[hash[h01 + iz1] & gradientsmask3d]; vector3 g111 = gradients3d[hash[h11 + iz1] & gradientsmask3d];  // calculate dot product using vector , respective fractions float v000 = dot(g000, tx0, ty0, tz0); float v100 = dot(g100, tx1, ty0, tz0); float v010 = dot(g010, tx0, ty1, tz0); float v110 = dot(g110, tx1, ty1, tz0); float v001 = dot(g001, tx0, ty0, tz1); float v101 = dot(g101, tx1, ty0, tz1); float v011 = dot(g011, tx0, ty1, tz1); float v111 = dot(g111, tx1, ty1, tz1);  // interpolate between 2 dot results using fractional numbers  l0 = lerp(v000, v100, tx); l1 = lerp(v010, v110, tx); l2 = lerp(l0,l1,ty);  l3 = lerp(v001, v101, tx); l4 = lerp(v011, v111, tx); l5 = lerp(l3,l4,ty);  l6 = lerp(l2,l5,tz); 

this results in single number representative of single unique point in space using same integer , gradient array. changing seed , reshuffling integer array , gradient array generate different number allowing bring uniqueness item using same code generate it.

the reason why integer array repeated set of numbers totalling 512 elements lookups not accidentally go on 0-255 limit +1 values added in code above cause.

if visualise line ( 1d x0 - x1 ), square ( 2d x0,y0 - x1,y1 ) , cube ( 3d x0,y0,z0 - x1,y1,z1 ) see code doing , part code similar.

i tried making own version of code despite several attempts can understand why everyone's noise code similar. there 1 way perlin , simplex noise work.

so goal work functionality shader equivalent code me, @ least, understand ins , outs of both perlin noise , shader programming. it's learning curve it's fun @ same time.

well hopefully, has answered questions. if want know whys , wherefores of ken perlin's improved perlin code check out following:

http://http.developer.nvidia.com/gpugems/gpugems_ch05.html - visual of cube


Comments

Popular posts from this blog

ruby - Trying to change last to "x"s to 23 -

jquery - Clone last and append item to closest class -

css - Can I use the :after pseudo-element on an input field? -