Advertisement
Delfigamer

perlin, source

Apr 11th, 2016
396
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.41 KB | None | 0 0
  1. #define STB_PERLIN_IMPLEMENTATION
  2.  
  3. // stb_perlin.h - v0.2 - perlin noise
  4. // public domain single-file C implementation by Sean Barrett
  5. //
  6. // LICENSE
  7. //
  8. //   This software is dual-licensed to the public domain and under the following
  9. //   license: you are granted a perpetual, irrevocable license to copy, modify,
  10. //   publish, and distribute this file as you see fit.
  11. //
  12. //
  13. // to create the implementation,
  14. //     #define STB_PERLIN_IMPLEMENTATION
  15. // in *one* C/CPP file that includes this file.
  16.  
  17.  
  18. // Documentation:
  19. //
  20. // float  stb_perlin_noise3( float x,
  21. //                           float y,
  22. //                           float z,
  23. //                           int   x_wrap=0,
  24. //                           int   y_wrap=0,
  25. //                           int   z_wrap=0)
  26. //
  27. // This function computes a random value at the coordinate (x,y,z).
  28. // Adjacent random values are continuous but the noise fluctuates
  29. // its randomness with period 1, i.e. takes on wholly unrelated values
  30. // at integer points. Specifically, this implements Ken Perlin's
  31. // revised noise function from 2002.
  32. //
  33. // The "wrap" parameters can be used to create wraparound noise that
  34. // wraps at powers of two. The numbers MUST be powers of two. Specify
  35. // 0 to mean "don't care". (The noise always wraps every 256 due
  36. // details of the implementation, even if you ask for larger or no
  37. // wrapping.)
  38.  
  39.  
  40. #ifdef __cplusplus
  41. extern "C" float stb_perlin_noise3(float x, float y, float z, int x_wrap=0, int y_wrap=0, int z_wrap=0);
  42. #else
  43. extern float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap);
  44. #endif
  45.  
  46. #ifdef STB_PERLIN_IMPLEMENTATION
  47.  
  48. #include <math.h> // floor()
  49.  
  50. // not same permutation table as Perlin's reference to avoid copyright issues;
  51. // Perlin's table can be found at http://mrl.nyu.edu/~perlin/noise/
  52. // @OPTIMIZE: should this be unsigned char instead of int for cache?
  53. static int stb__perlin_randtab[512] =
  54. {
  55.    23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123,
  56.    152, 238, 145, 45, 171, 114, 253, 10, 192, 136, 4, 157, 249, 30, 35, 72,
  57.    175, 63, 77, 90, 181, 16, 96, 111, 133, 104, 75, 162, 93, 56, 66, 240,
  58.    8, 50, 84, 229, 49, 210, 173, 239, 141, 1, 87, 18, 2, 198, 143, 57,
  59.    225, 160, 58, 217, 168, 206, 245, 204, 199, 6, 73, 60, 20, 230, 211, 233,
  60.    94, 200, 88, 9, 74, 155, 33, 15, 219, 130, 226, 202, 83, 236, 42, 172,
  61.    165, 218, 55, 222, 46, 107, 98, 154, 109, 67, 196, 178, 127, 158, 13, 243,
  62.    65, 79, 166, 248, 25, 224, 115, 80, 68, 51, 184, 128, 232, 208, 151, 122,
  63.    26, 212, 105, 43, 179, 213, 235, 148, 146, 89, 14, 195, 28, 78, 112, 76,
  64.    250, 47, 24, 251, 140, 108, 186, 190, 228, 170, 183, 139, 39, 188, 244, 246,
  65.    132, 48, 119, 144, 180, 138, 134, 193, 82, 182, 120, 121, 86, 220, 209, 3,
  66.    91, 241, 149, 85, 205, 150, 113, 216, 31, 100, 41, 164, 177, 214, 153, 231,
  67.    38, 71, 185, 174, 97, 201, 29, 95, 7, 92, 54, 254, 191, 118, 34, 221,
  68.    131, 11, 163, 99, 234, 81, 227, 147, 156, 176, 17, 142, 69, 12, 110, 62,
  69.    27, 255, 0, 194, 59, 116, 242, 252, 19, 21, 187, 53, 207, 129, 64, 135,
  70.    61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5,
  71.  
  72.    // and a second copy so we don't need an extra mask or static initializer
  73.    23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123,
  74.    152, 238, 145, 45, 171, 114, 253, 10, 192, 136, 4, 157, 249, 30, 35, 72,
  75.    175, 63, 77, 90, 181, 16, 96, 111, 133, 104, 75, 162, 93, 56, 66, 240,
  76.    8, 50, 84, 229, 49, 210, 173, 239, 141, 1, 87, 18, 2, 198, 143, 57,
  77.    225, 160, 58, 217, 168, 206, 245, 204, 199, 6, 73, 60, 20, 230, 211, 233,
  78.    94, 200, 88, 9, 74, 155, 33, 15, 219, 130, 226, 202, 83, 236, 42, 172,
  79.    165, 218, 55, 222, 46, 107, 98, 154, 109, 67, 196, 178, 127, 158, 13, 243,
  80.    65, 79, 166, 248, 25, 224, 115, 80, 68, 51, 184, 128, 232, 208, 151, 122,
  81.    26, 212, 105, 43, 179, 213, 235, 148, 146, 89, 14, 195, 28, 78, 112, 76,
  82.    250, 47, 24, 251, 140, 108, 186, 190, 228, 170, 183, 139, 39, 188, 244, 246,
  83.    132, 48, 119, 144, 180, 138, 134, 193, 82, 182, 120, 121, 86, 220, 209, 3,
  84.    91, 241, 149, 85, 205, 150, 113, 216, 31, 100, 41, 164, 177, 214, 153, 231,
  85.    38, 71, 185, 174, 97, 201, 29, 95, 7, 92, 54, 254, 191, 118, 34, 221,
  86.    131, 11, 163, 99, 234, 81, 227, 147, 156, 176, 17, 142, 69, 12, 110, 62,
  87.    27, 255, 0, 194, 59, 116, 242, 252, 19, 21, 187, 53, 207, 129, 64, 135,
  88.    61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5,
  89. };
  90.  
  91. static float stb__perlin_lerp(float a, float b, float t)
  92. {
  93.    return a + (b-a) * t;
  94. }
  95.  
  96. // different grad function from Perlin's, but easy to modify to match reference
  97. static float stb__perlin_grad(int hash, float x, float y, float z)
  98. {
  99.    static float basis[12][4] =
  100.    {
  101.       {  1, 1, 0 },
  102.       { -1, 1, 0 },
  103.       {  1,-1, 0 },
  104.       { -1,-1, 0 },
  105.       {  1, 0, 1 },
  106.       { -1, 0, 1 },
  107.       {  1, 0,-1 },
  108.       { -1, 0,-1 },
  109.       {  0, 1, 1 },
  110.       {  0,-1, 1 },
  111.       {  0, 1,-1 },
  112.       {  0,-1,-1 },
  113.    };
  114.  
  115.    // perlin's gradient has 12 cases so some get used 1/16th of the time
  116.    // and some 2/16ths. We reduce bias by changing those fractions
  117.    // to 5/16ths and 6/16ths, and the same 4 cases get the extra weight.
  118.    static unsigned char indices[64] =
  119.    {
  120.       0,1,2,3,4,5,6,7,8,9,10,11,
  121.       0,9,1,11,
  122.       0,1,2,3,4,5,6,7,8,9,10,11,
  123.       0,1,2,3,4,5,6,7,8,9,10,11,
  124.       0,1,2,3,4,5,6,7,8,9,10,11,
  125.       0,1,2,3,4,5,6,7,8,9,10,11,
  126.    };
  127.  
  128.    // if you use reference permutation table, change 63 below to 15 to match reference
  129.    float *grad = basis[indices[hash & 63]];
  130.    return grad[0]*x + grad[1]*y + grad[2]*z;
  131. }
  132.  
  133. float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap)
  134. {
  135.    float u,v,w;
  136.    float n000,n001,n010,n011,n100,n101,n110,n111;
  137.    float n00,n01,n10,n11;
  138.    float n0,n1;
  139.  
  140.    unsigned int x_mask = (x_wrap-1) & 255;
  141.    unsigned int y_mask = (y_wrap-1) & 255;
  142.    unsigned int z_mask = (z_wrap-1) & 255;
  143.    int px = (int) floor(x);
  144.    int py = (int) floor(y);
  145.    int pz = (int) floor(z);
  146.    int x0 = px & x_mask, x1 = (px+1) & x_mask;
  147.    int y0 = py & y_mask, y1 = (py+1) & y_mask;
  148.    int z0 = pz & z_mask, z1 = (pz+1) & z_mask;
  149.    int r0,r1, r00,r01,r10,r11;
  150.  
  151.    #define stb__perlin_ease(a)   (((a*6-15)*a + 10) * a * a * a)
  152.  
  153.    x -= px; u = stb__perlin_ease(x);
  154.    y -= py; v = stb__perlin_ease(y);
  155.    z -= pz; w = stb__perlin_ease(z);
  156.  
  157.    r0 = stb__perlin_randtab[x0];
  158.    r1 = stb__perlin_randtab[x1];
  159.  
  160.    r00 = stb__perlin_randtab[r0+y0];
  161.    r01 = stb__perlin_randtab[r0+y1];
  162.    r10 = stb__perlin_randtab[r1+y0];
  163.    r11 = stb__perlin_randtab[r1+y1];
  164.  
  165.    n000 = stb__perlin_grad(stb__perlin_randtab[r00+z0], x  , y  , z   );
  166.    n001 = stb__perlin_grad(stb__perlin_randtab[r00+z1], x  , y  , z-1 );
  167.    n010 = stb__perlin_grad(stb__perlin_randtab[r01+z0], x  , y-1, z   );
  168.    n011 = stb__perlin_grad(stb__perlin_randtab[r01+z1], x  , y-1, z-1 );
  169.    n100 = stb__perlin_grad(stb__perlin_randtab[r10+z0], x-1, y  , z   );
  170.    n101 = stb__perlin_grad(stb__perlin_randtab[r10+z1], x-1, y  , z-1 );
  171.    n110 = stb__perlin_grad(stb__perlin_randtab[r11+z0], x-1, y-1, z   );
  172.    n111 = stb__perlin_grad(stb__perlin_randtab[r11+z1], x-1, y-1, z-1 );
  173.  
  174.    n00 = stb__perlin_lerp(n000,n001,w);
  175.    n01 = stb__perlin_lerp(n010,n011,w);
  176.    n10 = stb__perlin_lerp(n100,n101,w);
  177.    n11 = stb__perlin_lerp(n110,n111,w);
  178.  
  179.    n0 = stb__perlin_lerp(n00,n01,v);
  180.    n1 = stb__perlin_lerp(n10,n11,v);
  181.  
  182.    return stb__perlin_lerp(n0,n1,u);
  183. }
  184. #endif  // STB_PERLIN_IMPLEMENTATION
  185.  
  186. //==============================================================================
  187.  
  188. float stb_perlin_noise3_no_floor(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap)
  189. {
  190.    float u,v,w;
  191.    float n000,n001,n010,n011,n100,n101,n110,n111;
  192.    float n00,n01,n10,n11;
  193.    float n0,n1;
  194.  
  195.    unsigned int x_mask = (x_wrap-1) & 255;
  196.    unsigned int y_mask = (y_wrap-1) & 255;
  197.    unsigned int z_mask = (z_wrap-1) & 255;
  198.    int px = (int) x; px -= (x<0);
  199.    int py = (int) y; py -= (y<0);
  200.    int pz = (int) z; pz -= (z<0);
  201.    int x0 = px & x_mask, x1 = (px+1) & x_mask;
  202.    int y0 = py & y_mask, y1 = (py+1) & y_mask;
  203.    int z0 = pz & z_mask, z1 = (pz+1) & z_mask;
  204.    int r0,r1, r00,r01,r10,r11;
  205.  
  206.    #define stb__perlin_ease(a)   (((a*6-15)*a + 10) * a * a * a)
  207.  
  208.    x -= px; u = stb__perlin_ease(x);
  209.    y -= py; v = stb__perlin_ease(y);
  210.    z -= pz; w = stb__perlin_ease(z);
  211.  
  212.    r0 = stb__perlin_randtab[x0];
  213.    r1 = stb__perlin_randtab[x1];
  214.  
  215.    r00 = stb__perlin_randtab[r0+y0];
  216.    r01 = stb__perlin_randtab[r0+y1];
  217.    r10 = stb__perlin_randtab[r1+y0];
  218.    r11 = stb__perlin_randtab[r1+y1];
  219.  
  220.    n000 = stb__perlin_grad(stb__perlin_randtab[r00+z0], x  , y  , z   );
  221.    n001 = stb__perlin_grad(stb__perlin_randtab[r00+z1], x  , y  , z-1 );
  222.    n010 = stb__perlin_grad(stb__perlin_randtab[r01+z0], x  , y-1, z   );
  223.    n011 = stb__perlin_grad(stb__perlin_randtab[r01+z1], x  , y-1, z-1 );
  224.    n100 = stb__perlin_grad(stb__perlin_randtab[r10+z0], x-1, y  , z   );
  225.    n101 = stb__perlin_grad(stb__perlin_randtab[r10+z1], x-1, y  , z-1 );
  226.    n110 = stb__perlin_grad(stb__perlin_randtab[r11+z0], x-1, y-1, z   );
  227.    n111 = stb__perlin_grad(stb__perlin_randtab[r11+z1], x-1, y-1, z-1 );
  228.  
  229.    n00 = stb__perlin_lerp(n000,n001,w);
  230.    n01 = stb__perlin_lerp(n010,n011,w);
  231.    n10 = stb__perlin_lerp(n100,n101,w);
  232.    n11 = stb__perlin_lerp(n110,n111,w);
  233.  
  234.    n0 = stb__perlin_lerp(n00,n01,v);
  235.    n1 = stb__perlin_lerp(n10,n11,v);
  236.  
  237.    return stb__perlin_lerp(n0,n1,u);
  238. }
  239.  
  240. //==============================================================================
  241.  
  242. #include <cstdio>
  243. #include <ctime>
  244.  
  245. static const int M=32;
  246. static const int N=1024;
  247.  
  248. float tex[M][M];
  249.  
  250. int main()
  251. {
  252.     const float du=1.0f/float(M);
  253.     const float dv=1.0f/float(M);
  254.  
  255.     float fu,fv;
  256.  
  257.     double t;
  258.  
  259.     t=double(clock());
  260.     for(int i=0;i<N;++i)
  261.     {
  262.         fv=0.5f*dv;
  263.         for(int iv=0;iv<M;++iv)
  264.         {
  265.             fu=0.5f*du;
  266.             for(int iu=0;iu<M;++iu)
  267.             {
  268.                 tex[iv][iu]=stb_perlin_noise3(fu,fv,0.5f,M,M,M);
  269.                 fu+=du;
  270.             }
  271.             fv+=dv;
  272.         }
  273.     }
  274.     t=double(clock())-t;
  275.     printf("stb_perlin_noise3: %.1f ns/call\n",1.0e+9*t/(double(N)*double(M*M)*double(CLOCKS_PER_SEC)));
  276.  
  277.     t=double(clock());
  278.     for(int i=0;i<N;++i)
  279.     {
  280.         fv=0.5f*dv;
  281.         for(int iv=0;iv<M;++iv)
  282.         {
  283.             fu=0.5f*du;
  284.             for(int iu=0;iu<M;++iu)
  285.             {
  286.                 tex[iv][iu]=stb_perlin_noise3_no_floor(fu,fv,0.5f,M,M,M);
  287.                 fu+=du;
  288.             }
  289.             fv+=dv;
  290.         }
  291.     }
  292.     t=double(clock())-t;
  293.     printf("stb_perlin_noise3_no_floor: %.1f ns/call\n",1.0e+9*t/(double(N)*double(M*M)*double(CLOCKS_PER_SEC)));
  294.  
  295.     return 0;
  296. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement