You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

416 lines
16 KiB

  1. /*
  2. * A fast javascript implementation of simplex noise by Jonas Wagner
  3. *
  4. * Based on a speed-improved simplex noise algorithm for 2D, 3D and 4D in Java.
  5. * Which is based on example code by Stefan Gustavson (stegu@itn.liu.se).
  6. * With Optimisations by Peter Eastman (peastman@drizzle.stanford.edu).
  7. * Better rank ordering method by Stefan Gustavson in 2012.
  8. *
  9. *
  10. * Copyright (C) 2016 Jonas Wagner
  11. *
  12. * Permission is hereby granted, free of charge, to any person obtaining
  13. * a copy of this software and associated documentation files (the
  14. * "Software"), to deal in the Software without restriction, including
  15. * without limitation the rights to use, copy, modify, merge, publish,
  16. * distribute, sublicense, and/or sell copies of the Software, and to
  17. * permit persons to whom the Software is furnished to do so, subject to
  18. * the following conditions:
  19. *
  20. * The above copyright notice and this permission notice shall be
  21. * included in all copies or substantial portions of the Software.
  22. *
  23. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  27. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  28. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  29. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  30. *
  31. */
  32. (function() {
  33. 'use strict';
  34. var F2 = 0.5 * (Math.sqrt(3.0) - 1.0);
  35. var G2 = (3.0 - Math.sqrt(3.0)) / 6.0;
  36. var F3 = 1.0 / 3.0;
  37. var G3 = 1.0 / 6.0;
  38. var F4 = (Math.sqrt(5.0) - 1.0) / 4.0;
  39. var G4 = (5.0 - Math.sqrt(5.0)) / 20.0;
  40. function SimplexNoise(random) {
  41. if (!random) random = Math.random;
  42. this.p = buildPermutationTable(random);
  43. this.perm = new Uint8Array(512);
  44. this.permMod12 = new Uint8Array(512);
  45. for (var i = 0; i < 512; i++) {
  46. this.perm[i] = this.p[i & 255];
  47. this.permMod12[i] = this.perm[i] % 12;
  48. }
  49. }
  50. SimplexNoise.prototype = {
  51. grad3: new Float32Array([1, 1, 0,
  52. -1, 1, 0,
  53. 1, -1, 0,
  54. -1, -1, 0,
  55. 1, 0, 1,
  56. -1, 0, 1,
  57. 1, 0, -1,
  58. -1, 0, -1,
  59. 0, 1, 1,
  60. 0, -1, 1,
  61. 0, 1, -1,
  62. 0, -1, -1]),
  63. grad4: new Float32Array([0, 1, 1, 1, 0, 1, 1, -1, 0, 1, -1, 1, 0, 1, -1, -1,
  64. 0, -1, 1, 1, 0, -1, 1, -1, 0, -1, -1, 1, 0, -1, -1, -1,
  65. 1, 0, 1, 1, 1, 0, 1, -1, 1, 0, -1, 1, 1, 0, -1, -1,
  66. -1, 0, 1, 1, -1, 0, 1, -1, -1, 0, -1, 1, -1, 0, -1, -1,
  67. 1, 1, 0, 1, 1, 1, 0, -1, 1, -1, 0, 1, 1, -1, 0, -1,
  68. -1, 1, 0, 1, -1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, -1,
  69. 1, 1, 1, 0, 1, 1, -1, 0, 1, -1, 1, 0, 1, -1, -1, 0,
  70. -1, 1, 1, 0, -1, 1, -1, 0, -1, -1, 1, 0, -1, -1, -1, 0]),
  71. noise2D: function(xin, yin) {
  72. var permMod12 = this.permMod12;
  73. var perm = this.perm;
  74. var grad3 = this.grad3;
  75. var n0 = 0; // Noise contributions from the three corners
  76. var n1 = 0;
  77. var n2 = 0;
  78. // Skew the input space to determine which simplex cell we're in
  79. var s = (xin + yin) * F2; // Hairy factor for 2D
  80. var i = Math.floor(xin + s);
  81. var j = Math.floor(yin + s);
  82. var t = (i + j) * G2;
  83. var X0 = i - t; // Unskew the cell origin back to (x,y) space
  84. var Y0 = j - t;
  85. var x0 = xin - X0; // The x,y distances from the cell origin
  86. var y0 = yin - Y0;
  87. // For the 2D case, the simplex shape is an equilateral triangle.
  88. // Determine which simplex we are in.
  89. var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
  90. if (x0 > y0) {
  91. i1 = 1;
  92. j1 = 0;
  93. } // lower triangle, XY order: (0,0)->(1,0)->(1,1)
  94. else {
  95. i1 = 0;
  96. j1 = 1;
  97. } // upper triangle, YX order: (0,0)->(0,1)->(1,1)
  98. // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
  99. // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
  100. // c = (3-sqrt(3))/6
  101. var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
  102. var y1 = y0 - j1 + G2;
  103. var x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords
  104. var y2 = y0 - 1.0 + 2.0 * G2;
  105. // Work out the hashed gradient indices of the three simplex corners
  106. var ii = i & 255;
  107. var jj = j & 255;
  108. // Calculate the contribution from the three corners
  109. var t0 = 0.5 - x0 * x0 - y0 * y0;
  110. if (t0 >= 0) {
  111. var gi0 = permMod12[ii + perm[jj]] * 3;
  112. t0 *= t0;
  113. n0 = t0 * t0 * (grad3[gi0] * x0 + grad3[gi0 + 1] * y0); // (x,y) of grad3 used for 2D gradient
  114. }
  115. var t1 = 0.5 - x1 * x1 - y1 * y1;
  116. if (t1 >= 0) {
  117. var gi1 = permMod12[ii + i1 + perm[jj + j1]] * 3;
  118. t1 *= t1;
  119. n1 = t1 * t1 * (grad3[gi1] * x1 + grad3[gi1 + 1] * y1);
  120. }
  121. var t2 = 0.5 - x2 * x2 - y2 * y2;
  122. if (t2 >= 0) {
  123. var gi2 = permMod12[ii + 1 + perm[jj + 1]] * 3;
  124. t2 *= t2;
  125. n2 = t2 * t2 * (grad3[gi2] * x2 + grad3[gi2 + 1] * y2);
  126. }
  127. // Add contributions from each corner to get the final noise value.
  128. // The result is scaled to return values in the interval [-1,1].
  129. return 70.0 * (n0 + n1 + n2);
  130. },
  131. // 3D simplex noise
  132. noise3D: function(xin, yin, zin) {
  133. var permMod12 = this.permMod12;
  134. var perm = this.perm;
  135. var grad3 = this.grad3;
  136. var n0, n1, n2, n3; // Noise contributions from the four corners
  137. // Skew the input space to determine which simplex cell we're in
  138. var s = (xin + yin + zin) * F3; // Very nice and simple skew factor for 3D
  139. var i = Math.floor(xin + s);
  140. var j = Math.floor(yin + s);
  141. var k = Math.floor(zin + s);
  142. var t = (i + j + k) * G3;
  143. var X0 = i - t; // Unskew the cell origin back to (x,y,z) space
  144. var Y0 = j - t;
  145. var Z0 = k - t;
  146. var x0 = xin - X0; // The x,y,z distances from the cell origin
  147. var y0 = yin - Y0;
  148. var z0 = zin - Z0;
  149. // For the 3D case, the simplex shape is a slightly irregular tetrahedron.
  150. // Determine which simplex we are in.
  151. var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
  152. var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
  153. if (x0 >= y0) {
  154. if (y0 >= z0) {
  155. i1 = 1;
  156. j1 = 0;
  157. k1 = 0;
  158. i2 = 1;
  159. j2 = 1;
  160. k2 = 0;
  161. } // X Y Z order
  162. else if (x0 >= z0) {
  163. i1 = 1;
  164. j1 = 0;
  165. k1 = 0;
  166. i2 = 1;
  167. j2 = 0;
  168. k2 = 1;
  169. } // X Z Y order
  170. else {
  171. i1 = 0;
  172. j1 = 0;
  173. k1 = 1;
  174. i2 = 1;
  175. j2 = 0;
  176. k2 = 1;
  177. } // Z X Y order
  178. }
  179. else { // x0<y0
  180. if (y0 < z0) {
  181. i1 = 0;
  182. j1 = 0;
  183. k1 = 1;
  184. i2 = 0;
  185. j2 = 1;
  186. k2 = 1;
  187. } // Z Y X order
  188. else if (x0 < z0) {
  189. i1 = 0;
  190. j1 = 1;
  191. k1 = 0;
  192. i2 = 0;
  193. j2 = 1;
  194. k2 = 1;
  195. } // Y Z X order
  196. else {
  197. i1 = 0;
  198. j1 = 1;
  199. k1 = 0;
  200. i2 = 1;
  201. j2 = 1;
  202. k2 = 0;
  203. } // Y X Z order
  204. }
  205. // A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
  206. // a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
  207. // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
  208. // c = 1/6.
  209. var x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords
  210. var y1 = y0 - j1 + G3;
  211. var z1 = z0 - k1 + G3;
  212. var x2 = x0 - i2 + 2.0 * G3; // Offsets for third corner in (x,y,z) coords
  213. var y2 = y0 - j2 + 2.0 * G3;
  214. var z2 = z0 - k2 + 2.0 * G3;
  215. var x3 = x0 - 1.0 + 3.0 * G3; // Offsets for last corner in (x,y,z) coords
  216. var y3 = y0 - 1.0 + 3.0 * G3;
  217. var z3 = z0 - 1.0 + 3.0 * G3;
  218. // Work out the hashed gradient indices of the four simplex corners
  219. var ii = i & 255;
  220. var jj = j & 255;
  221. var kk = k & 255;
  222. // Calculate the contribution from the four corners
  223. var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;
  224. if (t0 < 0) n0 = 0.0;
  225. else {
  226. var gi0 = permMod12[ii + perm[jj + perm[kk]]] * 3;
  227. t0 *= t0;
  228. n0 = t0 * t0 * (grad3[gi0] * x0 + grad3[gi0 + 1] * y0 + grad3[gi0 + 2] * z0);
  229. }
  230. var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
  231. if (t1 < 0) n1 = 0.0;
  232. else {
  233. var gi1 = permMod12[ii + i1 + perm[jj + j1 + perm[kk + k1]]] * 3;
  234. t1 *= t1;
  235. n1 = t1 * t1 * (grad3[gi1] * x1 + grad3[gi1 + 1] * y1 + grad3[gi1 + 2] * z1);
  236. }
  237. var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2;
  238. if (t2 < 0) n2 = 0.0;
  239. else {
  240. var gi2 = permMod12[ii + i2 + perm[jj + j2 + perm[kk + k2]]] * 3;
  241. t2 *= t2;
  242. n2 = t2 * t2 * (grad3[gi2] * x2 + grad3[gi2 + 1] * y2 + grad3[gi2 + 2] * z2);
  243. }
  244. var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3;
  245. if (t3 < 0) n3 = 0.0;
  246. else {
  247. var gi3 = permMod12[ii + 1 + perm[jj + 1 + perm[kk + 1]]] * 3;
  248. t3 *= t3;
  249. n3 = t3 * t3 * (grad3[gi3] * x3 + grad3[gi3 + 1] * y3 + grad3[gi3 + 2] * z3);
  250. }
  251. // Add contributions from each corner to get the final noise value.
  252. // The result is scaled to stay just inside [-1,1]
  253. return 32.0 * (n0 + n1 + n2 + n3);
  254. },
  255. // 4D simplex noise, better simplex rank ordering method 2012-03-09
  256. noise4D: function(x, y, z, w) {
  257. var permMod12 = this.permMod12;
  258. var perm = this.perm;
  259. var grad4 = this.grad4;
  260. var n0, n1, n2, n3, n4; // Noise contributions from the five corners
  261. // Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in
  262. var s = (x + y + z + w) * F4; // Factor for 4D skewing
  263. var i = Math.floor(x + s);
  264. var j = Math.floor(y + s);
  265. var k = Math.floor(z + s);
  266. var l = Math.floor(w + s);
  267. var t = (i + j + k + l) * G4; // Factor for 4D unskewing
  268. var X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space
  269. var Y0 = j - t;
  270. var Z0 = k - t;
  271. var W0 = l - t;
  272. var x0 = x - X0; // The x,y,z,w distances from the cell origin
  273. var y0 = y - Y0;
  274. var z0 = z - Z0;
  275. var w0 = w - W0;
  276. // For the 4D case, the simplex is a 4D shape I won't even try to describe.
  277. // To find out which of the 24 possible simplices we're in, we need to
  278. // determine the magnitude ordering of x0, y0, z0 and w0.
  279. // Six pair-wise comparisons are performed between each possible pair
  280. // of the four coordinates, and the results are used to rank the numbers.
  281. var rankx = 0;
  282. var ranky = 0;
  283. var rankz = 0;
  284. var rankw = 0;
  285. if (x0 > y0) rankx++;
  286. else ranky++;
  287. if (x0 > z0) rankx++;
  288. else rankz++;
  289. if (x0 > w0) rankx++;
  290. else rankw++;
  291. if (y0 > z0) ranky++;
  292. else rankz++;
  293. if (y0 > w0) ranky++;
  294. else rankw++;
  295. if (z0 > w0) rankz++;
  296. else rankw++;
  297. var i1, j1, k1, l1; // The integer offsets for the second simplex corner
  298. var i2, j2, k2, l2; // The integer offsets for the third simplex corner
  299. var i3, j3, k3, l3; // The integer offsets for the fourth simplex corner
  300. // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
  301. // Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
  302. // impossible. Only the 24 indices which have non-zero entries make any sense.
  303. // We use a thresholding to set the coordinates in turn from the largest magnitude.
  304. // Rank 3 denotes the largest coordinate.
  305. i1 = rankx >= 3 ? 1 : 0;
  306. j1 = ranky >= 3 ? 1 : 0;
  307. k1 = rankz >= 3 ? 1 : 0;
  308. l1 = rankw >= 3 ? 1 : 0;
  309. // Rank 2 denotes the second largest coordinate.
  310. i2 = rankx >= 2 ? 1 : 0;
  311. j2 = ranky >= 2 ? 1 : 0;
  312. k2 = rankz >= 2 ? 1 : 0;
  313. l2 = rankw >= 2 ? 1 : 0;
  314. // Rank 1 denotes the second smallest coordinate.
  315. i3 = rankx >= 1 ? 1 : 0;
  316. j3 = ranky >= 1 ? 1 : 0;
  317. k3 = rankz >= 1 ? 1 : 0;
  318. l3 = rankw >= 1 ? 1 : 0;
  319. // The fifth corner has all coordinate offsets = 1, so no need to compute that.
  320. var x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords
  321. var y1 = y0 - j1 + G4;
  322. var z1 = z0 - k1 + G4;
  323. var w1 = w0 - l1 + G4;
  324. var x2 = x0 - i2 + 2.0 * G4; // Offsets for third corner in (x,y,z,w) coords
  325. var y2 = y0 - j2 + 2.0 * G4;
  326. var z2 = z0 - k2 + 2.0 * G4;
  327. var w2 = w0 - l2 + 2.0 * G4;
  328. var x3 = x0 - i3 + 3.0 * G4; // Offsets for fourth corner in (x,y,z,w) coords
  329. var y3 = y0 - j3 + 3.0 * G4;
  330. var z3 = z0 - k3 + 3.0 * G4;
  331. var w3 = w0 - l3 + 3.0 * G4;
  332. var x4 = x0 - 1.0 + 4.0 * G4; // Offsets for last corner in (x,y,z,w) coords
  333. var y4 = y0 - 1.0 + 4.0 * G4;
  334. var z4 = z0 - 1.0 + 4.0 * G4;
  335. var w4 = w0 - 1.0 + 4.0 * G4;
  336. // Work out the hashed gradient indices of the five simplex corners
  337. var ii = i & 255;
  338. var jj = j & 255;
  339. var kk = k & 255;
  340. var ll = l & 255;
  341. // Calculate the contribution from the five corners
  342. var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
  343. if (t0 < 0) n0 = 0.0;
  344. else {
  345. var gi0 = (perm[ii + perm[jj + perm[kk + perm[ll]]]] % 32) * 4;
  346. t0 *= t0;
  347. n0 = t0 * t0 * (grad4[gi0] * x0 + grad4[gi0 + 1] * y0 + grad4[gi0 + 2] * z0 + grad4[gi0 + 3] * w0);
  348. }
  349. var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
  350. if (t1 < 0) n1 = 0.0;
  351. else {
  352. var gi1 = (perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]]]] % 32) * 4;
  353. t1 *= t1;
  354. n1 = t1 * t1 * (grad4[gi1] * x1 + grad4[gi1 + 1] * y1 + grad4[gi1 + 2] * z1 + grad4[gi1 + 3] * w1);
  355. }
  356. var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
  357. if (t2 < 0) n2 = 0.0;
  358. else {
  359. var gi2 = (perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]]]] % 32) * 4;
  360. t2 *= t2;
  361. n2 = t2 * t2 * (grad4[gi2] * x2 + grad4[gi2 + 1] * y2 + grad4[gi2 + 2] * z2 + grad4[gi2 + 3] * w2);
  362. }
  363. var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
  364. if (t3 < 0) n3 = 0.0;
  365. else {
  366. var gi3 = (perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]]]] % 32) * 4;
  367. t3 *= t3;
  368. n3 = t3 * t3 * (grad4[gi3] * x3 + grad4[gi3 + 1] * y3 + grad4[gi3 + 2] * z3 + grad4[gi3 + 3] * w3);
  369. }
  370. var t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
  371. if (t4 < 0) n4 = 0.0;
  372. else {
  373. var gi4 = (perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32) * 4;
  374. t4 *= t4;
  375. n4 = t4 * t4 * (grad4[gi4] * x4 + grad4[gi4 + 1] * y4 + grad4[gi4 + 2] * z4 + grad4[gi4 + 3] * w4);
  376. }
  377. // Sum up and scale the result to cover the range [-1,1]
  378. return 27.0 * (n0 + n1 + n2 + n3 + n4);
  379. }
  380. };
  381. function buildPermutationTable(random) {
  382. var i;
  383. var p = new Uint8Array(256);
  384. for (i = 0; i < 256; i++) {
  385. p[i] = i;
  386. }
  387. for (i = 0; i < 255; i++) {
  388. var r = i + ~~(random() * (256 - i));
  389. var aux = p[i];
  390. p[i] = p[r];
  391. p[r] = aux;
  392. }
  393. return p;
  394. }
  395. SimplexNoise._buildPermutationTable = buildPermutationTable;
  396. // amd
  397. if (typeof define !== 'undefined' && define.amd) define(function() {return SimplexNoise;});
  398. // common js
  399. if (typeof exports !== 'undefined') exports.SimplexNoise = SimplexNoise;
  400. // browser
  401. else if (typeof window !== 'undefined') window.SimplexNoise = SimplexNoise;
  402. // nodejs
  403. if (typeof module !== 'undefined') {
  404. module.exports = SimplexNoise;
  405. }
  406. })();