Advertisement
Guest User

Perlin Noise

a guest
Apr 16th, 2014
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.40 KB | None | 0 0
  1. public static class Simplex {
  2.            
  3.             private static readonly float F2=0.366025403f; //0.5*(sqrt(3.0)-1.0)
  4.             private static readonly float G2=0.211324865f; //(3.0-sqrt(3.0))/6.0
  5.             private static readonly float F3=0.333333333f;
  6.             private static readonly float G3=0.166666667f;
  7.            
  8.             private static byte[] perm=Math.RandomByteArrayUnique2();
  9.            
  10.             public static float Noise(float x,float y,float z) {
  11.                
  12.                 float n0, n1, n2, n3; // Noise contributions from the four corners
  13.                
  14.                 // Skew the input space to determine which simplex cell we're in
  15.                 float s=(x + y + z) * F3; // Very nice and simple skew factor for 3D
  16.                 float xs=x + s;
  17.                 float ys=y + s;
  18.                 float zs=z + s;
  19.                 int i=Math.FloorToInt(xs);
  20.                 int j=Math.FloorToInt(ys);
  21.                 int k=Math.FloorToInt(zs);
  22.                
  23.                 float t=(float)(i + j + k) * G3;
  24.                 float X0=i - t; // Unskew the cell origin back to (x,y,z) space
  25.                 float Y0=j - t;
  26.                 float Z0=k - t;
  27.                 float x0=x - X0; // The x,y,z distances from the cell origin
  28.                 float y0=y - Y0;
  29.                 float z0=z - Z0;
  30.                
  31.                 // For the 3D case, the simplex shape is a slightly irregular tetrahedron.
  32.                 // Determine which simplex we are in.
  33.                 int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
  34.                 int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
  35.                
  36.                 /* This code would benefit from a backport from the GLSL version! */
  37.                 if(x0>=y0) {
  38.                     if(y0>=z0) {
  39.                         i1=1;
  40.                         j1=0;
  41.                         k1=0;
  42.                         i2=1;
  43.                         j2=1;
  44.                         k2=0;
  45.                     } // X Y Z order
  46.                     else if(x0>=z0) {
  47.                         i1=1;
  48.                         j1=0;
  49.                         k1=0;
  50.                         i2=1;
  51.                         j2=0;
  52.                         k2=1;
  53.                     } // X Z Y order
  54.                     else {
  55.                         i1=0;
  56.                         j1=0;
  57.                         k1=1;
  58.                         i2=1;
  59.                         j2=0;
  60.                         k2=1;
  61.                     } // Z X Y order
  62.                 } else { // x0<y0
  63.                     if(y0<z0) {
  64.                         i1=0;
  65.                         j1=0;
  66.                         k1=1;
  67.                         i2=0;
  68.                         j2=1;
  69.                         k2=1;
  70.                     } // Z Y X order
  71.                     else if(x0<z0) {
  72.                         i1=0;
  73.                         j1=1;
  74.                         k1=0;
  75.                         i2=0;
  76.                         j2=1;
  77.                         k2=1;
  78.                     } // Y Z X order
  79.                     else {
  80.                         i1=0;
  81.                         j1=1;
  82.                         k1=0;
  83.                         i2=1;
  84.                         j2=1;
  85.                         k2=0;
  86.                     } // Y X Z order
  87.                 }
  88.                
  89.                 // A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
  90.                 // a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
  91.                 // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
  92.                 // c = 1/6.
  93.                
  94.                 float x1=x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords
  95.                 float y1=y0 - j1 + G3;
  96.                 float z1=z0 - k1 + G3;
  97.                 float x2=x0 - i2 + 2.0f * G3; // Offsets for third corner in (x,y,z) coords
  98.                 float y2=y0 - j2 + 2.0f * G3;
  99.                 float z2=z0 - k2 + 2.0f * G3;
  100.                 float x3=x0 - 1.0f + 3.0f * G3; // Offsets for last corner in (x,y,z) coords
  101.                 float y3=y0 - 1.0f + 3.0f * G3;
  102.                 float z3=z0 - 1.0f + 3.0f * G3;
  103.                
  104.                 // Wrap the integer indices at 256, to avoid indexing perm[] out of bounds
  105.                 int ii=i % 256;
  106.                 int jj=j % 256;
  107.                 int kk=k % 256;
  108.                
  109.                 // Calculate the contribution from the four corners
  110.                 float t0=0.6f - x0 * x0 - y0 * y0 - z0 * z0;
  111.                 if(t0<0.0f)
  112.                     n0=0.0f;
  113.                 else {
  114.                     t0*=t0;
  115.                     n0=t0 * t0 * grad(perm[ii + perm[jj + perm[kk]]], x0, y0, z0);
  116.                 }
  117.                
  118.                 float t1=0.6f - x1 * x1 - y1 * y1 - z1 * z1;
  119.                 if(t1<0.0f)
  120.                     n1=0.0f;
  121.                 else {
  122.                     t1*=t1;
  123.                     n1=t1 * t1 * grad(perm[ii + i1 + perm[jj + j1 + perm[kk + k1]]], x1, y1, z1);
  124.                 }
  125.                
  126.                 float t2=0.6f - x2 * x2 - y2 * y2 - z2 * z2;
  127.                 if(t2<0.0f)
  128.                     n2=0.0f;
  129.                 else {
  130.                     t2*=t2;
  131.                     n2=t2 * t2 * grad(perm[ii + i2 + perm[jj + j2 + perm[kk + k2]]], x2, y2, z2);
  132.                 }
  133.                
  134.                 float t3=0.6f - x3 * x3 - y3 * y3 - z3 * z3;
  135.                 if(t3<0.0f)
  136.                     n3=0.0f;
  137.                 else {
  138.                     t3*=t3;
  139.                     n3=t3 * t3 * grad(perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]], x3, y3, z3);
  140.                 }
  141.                
  142.                 // Add contributions from each corner to get the final noise value.
  143.                 // The result is scaled to stay just inside [-1,1]
  144.                 return 32.0f * (n0 + n1 + n2 + n3); // TODO: The scale factor is preliminary!
  145.             }
  146.            
  147.             private static float grad(int hash,float x) {
  148.                 int h=hash & 15;
  149.                 float grad=1.0f + (h & 7);   // Gradient value 1.0, 2.0, ..., 8.0
  150.                 if((h & 8)!=0)
  151.                     grad=-grad;         // Set a random sign for the gradient
  152.                 return (grad * x);           // Multiply the gradient with the distance
  153.             }
  154.            
  155.             private static float grad(int hash,float x,float y) {
  156.                 int h=hash & 7;      // Convert low 3 bits of hash code
  157.                 float u=h<4 ? x : y;  // into 8 simple gradient directions,
  158.                 float v=h<4 ? y : x;  // and compute the dot product with (x,y).
  159.                 return ((h & 1)!=0 ? -u : u) + ((h & 2)!=0 ? -2.0f * v : 2.0f * v);
  160.             }
  161.            
  162.             private static float grad(int hash,float x,float y,float z) {
  163.                 int h=hash & 15;     // Convert low 4 bits of hash code into 12 simple
  164.                 float u=h<8 ? x : y; // gradient directions, and compute dot product.
  165.                 float v=h<4 ? y : h==12 || h==14 ? x : z; // Fix repeats at h = 12 to 15
  166.                 return ((h & 1)!=0 ? -u : u) + ((h & 2)!=0 ? -v : v);
  167.             }
  168.            
  169.             private static float grad(int hash,float x,float y,float z,float t) {
  170.                 int h=hash & 31;      // Convert low 5 bits of hash code into 32 simple
  171.                 float u=h<24 ? x : y; // gradient directions, and compute dot product.
  172.                 float v=h<16 ? y : z;
  173.                 float w=h<8 ? z : t;
  174.                 return ((h & 1)!=0 ? -u : u) + ((h & 2)!=0 ? -v : v) + ((h & 4)!=0 ? -w : w);
  175.             }
  176.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement