fork(5) download
  1. #include <cstdio>
  2. #include <cstdint>
  3.  
  4. #define STB_PERLIN_IMPLEMENTATION
  5.  
  6. // stb_perlin.h - v0.2 - perlin noise
  7. // public domain single-file C implementation by Sean Barrett
  8. //
  9. // to create the implementation,
  10. // #define STB_PERLIN_IMPLEMENTATION
  11. // in *one* C/CPP file that includes this file.
  12.  
  13.  
  14. // Documentation:
  15. //
  16. // float stb_perlin_noise3( float x,
  17. // float y,
  18. // float z,
  19. // int x_wrap=0,
  20. // int y_wrap=0,
  21. // int z_wrap=0)
  22. //
  23. // This function computes a random value at the coordinate (x,y,z).
  24. // Adjacent random values are continuous but the noise fluctuates
  25. // its randomness with period 1, i.e. takes on wholly unrelated values
  26. // at integer points. Specifically, this implements Ken Perlin's
  27. // revised noise function from 2002.
  28. //
  29. // The "wrap" parameters can be used to create wraparound noise that
  30. // wraps at powers of two. The numbers MUST be powers of two. Specify
  31. // 0 to mean "don't care". (The noise always wraps every 256 due
  32. // details of the implementation, even if you ask for larger or no
  33. // wrapping.)
  34.  
  35.  
  36. #ifdef __cplusplus
  37. extern "C" float stb_perlin_noise3(float x, float y, float z, int x_wrap=0, int y_wrap=0, int z_wrap=0);
  38. #else
  39. extern float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap);
  40. #endif
  41.  
  42. #ifdef STB_PERLIN_IMPLEMENTATION
  43.  
  44. #include <math.h> // floor()
  45.  
  46. // not same permutation table as Perlin's reference to avoid copyright issues;
  47. // Perlin's table can be found at http://m...content-available-to-author-only...u.edu/~perlin/noise/
  48. // @OPTIMIZE: should this be unsigned char instead of int for cache?
  49. static int stb__perlin_randtab[512] =
  50. {
  51. 23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123,
  52. 152, 238, 145, 45, 171, 114, 253, 10, 192, 136, 4, 157, 249, 30, 35, 72,
  53. 175, 63, 77, 90, 181, 16, 96, 111, 133, 104, 75, 162, 93, 56, 66, 240,
  54. 8, 50, 84, 229, 49, 210, 173, 239, 141, 1, 87, 18, 2, 198, 143, 57,
  55. 225, 160, 58, 217, 168, 206, 245, 204, 199, 6, 73, 60, 20, 230, 211, 233,
  56. 94, 200, 88, 9, 74, 155, 33, 15, 219, 130, 226, 202, 83, 236, 42, 172,
  57. 165, 218, 55, 222, 46, 107, 98, 154, 109, 67, 196, 178, 127, 158, 13, 243,
  58. 65, 79, 166, 248, 25, 224, 115, 80, 68, 51, 184, 128, 232, 208, 151, 122,
  59. 26, 212, 105, 43, 179, 213, 235, 148, 146, 89, 14, 195, 28, 78, 112, 76,
  60. 250, 47, 24, 251, 140, 108, 186, 190, 228, 170, 183, 139, 39, 188, 244, 246,
  61. 132, 48, 119, 144, 180, 138, 134, 193, 82, 182, 120, 121, 86, 220, 209, 3,
  62. 91, 241, 149, 85, 205, 150, 113, 216, 31, 100, 41, 164, 177, 214, 153, 231,
  63. 38, 71, 185, 174, 97, 201, 29, 95, 7, 92, 54, 254, 191, 118, 34, 221,
  64. 131, 11, 163, 99, 234, 81, 227, 147, 156, 176, 17, 142, 69, 12, 110, 62,
  65. 27, 255, 0, 194, 59, 116, 242, 252, 19, 21, 187, 53, 207, 129, 64, 135,
  66. 61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5,
  67.  
  68. // and a second copy so we don't need an extra mask or static initializer
  69. 23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123,
  70. 152, 238, 145, 45, 171, 114, 253, 10, 192, 136, 4, 157, 249, 30, 35, 72,
  71. 175, 63, 77, 90, 181, 16, 96, 111, 133, 104, 75, 162, 93, 56, 66, 240,
  72. 8, 50, 84, 229, 49, 210, 173, 239, 141, 1, 87, 18, 2, 198, 143, 57,
  73. 225, 160, 58, 217, 168, 206, 245, 204, 199, 6, 73, 60, 20, 230, 211, 233,
  74. 94, 200, 88, 9, 74, 155, 33, 15, 219, 130, 226, 202, 83, 236, 42, 172,
  75. 165, 218, 55, 222, 46, 107, 98, 154, 109, 67, 196, 178, 127, 158, 13, 243,
  76. 65, 79, 166, 248, 25, 224, 115, 80, 68, 51, 184, 128, 232, 208, 151, 122,
  77. 26, 212, 105, 43, 179, 213, 235, 148, 146, 89, 14, 195, 28, 78, 112, 76,
  78. 250, 47, 24, 251, 140, 108, 186, 190, 228, 170, 183, 139, 39, 188, 244, 246,
  79. 132, 48, 119, 144, 180, 138, 134, 193, 82, 182, 120, 121, 86, 220, 209, 3,
  80. 91, 241, 149, 85, 205, 150, 113, 216, 31, 100, 41, 164, 177, 214, 153, 231,
  81. 38, 71, 185, 174, 97, 201, 29, 95, 7, 92, 54, 254, 191, 118, 34, 221,
  82. 131, 11, 163, 99, 234, 81, 227, 147, 156, 176, 17, 142, 69, 12, 110, 62,
  83. 27, 255, 0, 194, 59, 116, 242, 252, 19, 21, 187, 53, 207, 129, 64, 135,
  84. 61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5,
  85. };
  86.  
  87. static float stb__perlin_lerp(float a, float b, float t)
  88. {
  89. return a + (b-a) * t;
  90. }
  91.  
  92. // different grad function from Perlin's, but easy to modify to match reference
  93. static float stb__perlin_grad(int hash, float x, float y, float z)
  94. {
  95. static float basis[12][4] =
  96. {
  97. { 1, 1, 0 },
  98. { -1, 1, 0 },
  99. { 1,-1, 0 },
  100. { -1,-1, 0 },
  101. { 1, 0, 1 },
  102. { -1, 0, 1 },
  103. { 1, 0,-1 },
  104. { -1, 0,-1 },
  105. { 0, 1, 1 },
  106. { 0,-1, 1 },
  107. { 0, 1,-1 },
  108. { 0,-1,-1 },
  109. };
  110.  
  111. // perlin's gradient has 12 cases so some get used 1/16th of the time
  112. // and some 2/16ths. We reduce bias by changing those fractions
  113. // to 5/16ths and 6/16ths, and the same 4 cases get the extra weight.
  114. static unsigned char indices[64] =
  115. {
  116. 0,1,2,3,4,5,6,7,8,9,10,11,
  117. 0,9,1,11,
  118. 0,1,2,3,4,5,6,7,8,9,10,11,
  119. 0,1,2,3,4,5,6,7,8,9,10,11,
  120. 0,1,2,3,4,5,6,7,8,9,10,11,
  121. 0,1,2,3,4,5,6,7,8,9,10,11,
  122. };
  123.  
  124. // if you use reference permutation table, change 63 below to 15 to match reference
  125. float *grad = basis[indices[hash & 63]];
  126. return grad[0]*x + grad[1]*y + grad[2]*z;
  127. }
  128.  
  129. float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap)
  130. {
  131. float u,v,w;
  132. float n000,n001,n010,n011,n100,n101,n110,n111;
  133. float n00,n01,n10,n11;
  134. float n0,n1;
  135.  
  136. unsigned int x_mask = (x_wrap-1) & 255;
  137. unsigned int y_mask = (y_wrap-1) & 255;
  138. unsigned int z_mask = (z_wrap-1) & 255;
  139. int px = (int) floor(x);
  140. int py = (int) floor(y);
  141. int pz = (int) floor(z);
  142. int x0 = px & x_mask, x1 = (px+1) & x_mask;
  143. int y0 = py & y_mask, y1 = (py+1) & y_mask;
  144. int z0 = pz & z_mask, z1 = (pz+1) & z_mask;
  145. int r0,r1, r00,r01,r10,r11;
  146.  
  147. #define stb__perlin_ease(a) (((a*6-15)*a + 10) * a * a * a)
  148.  
  149. x -= px; u = stb__perlin_ease(x);
  150. y -= py; v = stb__perlin_ease(y);
  151. z -= pz; w = stb__perlin_ease(z);
  152.  
  153. r0 = stb__perlin_randtab[x0];
  154. r1 = stb__perlin_randtab[x1];
  155.  
  156. r00 = stb__perlin_randtab[r0+y0];
  157. r01 = stb__perlin_randtab[r0+y1];
  158. r10 = stb__perlin_randtab[r1+y0];
  159. r11 = stb__perlin_randtab[r1+y1];
  160.  
  161. n000 = stb__perlin_grad(stb__perlin_randtab[r00+z0], x , y , z );
  162. n001 = stb__perlin_grad(stb__perlin_randtab[r00+z1], x , y , z-1 );
  163. n010 = stb__perlin_grad(stb__perlin_randtab[r01+z0], x , y-1, z );
  164. n011 = stb__perlin_grad(stb__perlin_randtab[r01+z1], x , y-1, z-1 );
  165. n100 = stb__perlin_grad(stb__perlin_randtab[r10+z0], x-1, y , z );
  166. n101 = stb__perlin_grad(stb__perlin_randtab[r10+z1], x-1, y , z-1 );
  167. n110 = stb__perlin_grad(stb__perlin_randtab[r11+z0], x-1, y-1, z );
  168. n111 = stb__perlin_grad(stb__perlin_randtab[r11+z1], x-1, y-1, z-1 );
  169.  
  170. n00 = stb__perlin_lerp(n000,n001,w);
  171. n01 = stb__perlin_lerp(n010,n011,w);
  172. n10 = stb__perlin_lerp(n100,n101,w);
  173. n11 = stb__perlin_lerp(n110,n111,w);
  174.  
  175. n0 = stb__perlin_lerp(n00,n01,v);
  176. n1 = stb__perlin_lerp(n10,n11,v);
  177.  
  178. return stb__perlin_lerp(n0,n1,u);
  179. }
  180. #endif // STB_PERLIN_IMPLEMENTATION
  181.  
  182. uint64_t rdtsc()
  183. {
  184. uint64_t ret;
  185. asm volatile
  186. (
  187. "rdtsc"
  188. :"=A"(ret)
  189. );
  190. return ret;
  191. }
  192.  
  193. float image[1<<26];
  194.  
  195. int main()
  196. {
  197. for(uint32_t N=32;N<=256;N*=2)
  198. {
  199. uint32_t octaves=7;
  200. uint64_t tacts=rdtsc();
  201. float x,y,z,dx,dy,dz;
  202. for(uint32_t v=0;v<N;++v)
  203. {
  204. x=0.0f;
  205. y=float(v)/73.0f;
  206. z=float(v)/25.0f;
  207. dx=1.0f/256.0f;
  208. dy=1.0f/73.0f;
  209. dz=1.0f/53.0f;
  210. for(uint32_t u=0;u<N;++u)
  211. {
  212. image[N*v+u]=stb_perlin_noise3(x,y,z,0,0,0);
  213. x+=dx;
  214. z+=dz;
  215. }
  216. }
  217. tacts=rdtsc()-tacts;
  218. printf("N=%d, time: %.0f tacts per texel.\n",N,double(tacts)/double(N*N));
  219. }
  220. return 0;
  221. }
  222.  
Success #stdin #stdout 0.01s 265280KB
stdin
Standard input is empty
stdout
N=32, time: 472 tacts per texel.
N=64, time: 446 tacts per texel.
N=128, time: 450 tacts per texel.
N=256, time: 456 tacts per texel.