, 2010\n var s0 = 0;\n var s1 = 0;\n var s2 = 0;\n var c = 1;\n\n if (args.length == 0) {\n args = [+new Date];\n }\n var mash = Mash();\n s0 = mash(' ');\n s1 = mash(' ');\n s2 = mash(' ');\n\n for (var i = 0; i < args.length; i++) {\n s0 -= mash(args[i]);\n if (s0 < 0) {\n s0 += 1;\n }\n s1 -= mash(args[i]);\n if (s1 < 0) {\n s1 += 1;\n }\n s2 -= mash(args[i]);\n if (s2 < 0) {\n s2 += 1;\n }\n }\n mash = null;\n\n var random = function() {\n var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32\n s0 = s1;\n s1 = s2;\n return s2 = t - (c = t | 0);\n };\n random.uint32 = function() {\n return random() * 0x100000000; // 2^32\n };\n random.fract53 = function() {\n return random() + \n (random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53\n };\n random.version = 'Alea 0.9';\n random.args = args;\n\n // my own additions to sync state between two generators\n random.exportState = function(){\n return [s0, s1, s2, c];\n };\n random.importState = function(i){\n s0 = +i[0] || 0;\n s1 = +i[1] || 0;\n s2 = +i[2] || 0;\n c = +i[3] || 0;\n };\n \n return random;\n\n } (Array.prototype.slice.call(arguments)));\n }\n\n function Mash() {\n var n = 0xefc8249d;\n\n var mash = function(data) {\n data = data.toString();\n for (var i = 0; i < data.length; i++) {\n n += data.charCodeAt(i);\n var h = 0.02519603282416938 * n;\n n = h >>> 0;\n h -= n;\n h *= n;\n n = h >>> 0;\n h -= n;\n n += h * 0x100000000; // 2^32\n }\n return (n >>> 0) * 2.3283064365386963e-10; // 2^-32\n };\n\n mash.version = 'Mash 0.9';\n return mash;\n }\n}));\n\n\n//# sourceURL=webpack://WorleyNoise/./node_modules/alea/alea.js?");
107 |
108 | /***/ }),
109 |
110 | /***/ "./src/index.js":
111 | /*!**********************!*\
112 | !*** ./src/index.js ***!
113 | \**********************/
114 | /*! no static exports found */
115 | /***/ (function(module, exports, __webpack_require__) {
116 |
117 | "use strict";
118 | eval("\n\nvar _worleyNoise = _interopRequireDefault(__webpack_require__(/*! ./worley-noise */ \"./src/worley-noise.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nmodule.exports = _worleyNoise.default;\n\n//# sourceURL=webpack://WorleyNoise/./src/index.js?");
119 |
120 | /***/ }),
121 |
122 | /***/ "./src/worley-noise.js":
123 | /*!*****************************!*\
124 | !*** ./src/worley-noise.js ***!
125 | \*****************************/
126 | /*! no static exports found */
127 | /***/ (function(module, exports, __webpack_require__) {
128 |
129 | "use strict";
130 | eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.default = void 0;\n\nvar _alea = _interopRequireDefault(__webpack_require__(/*! alea */ \"./node_modules/alea/alea.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar WorleyNoise =\n/*#__PURE__*/\nfunction () {\n function WorleyNoise(config) {\n _classCallCheck(this, WorleyNoise);\n\n config = config || {};\n if (config.dim !== 2 && config.dim !== 3 && config.dim !== undefined) throw '\"dim\" can be 2 or 3';\n this._dim = config.dim || 2;\n this._rng = new _alea.default(config.seed || Math.random());\n this._points = [];\n\n for (var i = 0; i < config.numPoints; i++) {\n this._points.push({\n x: this._rng(),\n y: this._rng(),\n z: this._rng()\n });\n }\n }\n\n _createClass(WorleyNoise, [{\n key: \"addPoint\",\n value: function addPoint(coord) {\n this._points.push(coord);\n }\n }, {\n key: \"getEuclidean\",\n value: function getEuclidean(coord, k) {\n return Math.sqrt(this._calculateValue(coord, k, euclidean));\n }\n }, {\n key: \"getManhattan\",\n value: function getManhattan(coord, k) {\n return this._calculateValue(coord, k, manhattan);\n }\n }, {\n key: \"renderImage\",\n value: function renderImage(resolution, config) {\n var _this = this;\n\n config = config || {};\n var step = 1 / (resolution - 1);\n var img = [];\n\n var callback = config.callback || function (e, m) {\n return e(1);\n };\n\n var x, y;\n\n var e = function e(k) {\n return Math.sqrt(_this._calculateValue({\n x: x * step,\n y: y * step,\n z: config.z || 0\n }, k, euclidean));\n };\n\n var m = function m(k) {\n return _this._calculateValue({\n x: x * step,\n y: y * step,\n z: config.z || 0\n }, k, manhattan);\n };\n\n for (y = 0; y < resolution; ++y) {\n for (x = 0; x < resolution; ++x) {\n img[y * resolution + x] = callback(e, m);\n }\n }\n\n if (!config.normalize) return img;\n var min = Number.POSITIVE_INFINITY;\n var max = Number.NEGATIVE_INFINITY;\n img.forEach(function (v) {\n min = Math.min(min, v);\n max = Math.max(max, v);\n });\n var scale = 1 / (max - min);\n return img.map(function (v) {\n return (v - min) * scale;\n });\n }\n }, {\n key: \"_calculateValue\",\n value: function _calculateValue(coord, k, distFn) {\n var minDist;\n\n this._points.forEach(function (p) {\n p.selected = false;\n });\n\n for (var j = 0; j < k; ++j) {\n var minIdx = void 0;\n minDist = Number.POSITIVE_INFINITY;\n\n for (var i = 0; i < this._points.length; ++i) {\n var p = this._points[i];\n var dz = this._dim === 2 ? 0 : coord.z - p.z;\n var dist = distFn(coord.x - p.x, coord.y - p.y, dz);\n\n if (dist < minDist && !p.selected) {\n minDist = dist;\n minIdx = i;\n }\n }\n\n this._points[minIdx].selected = true;\n }\n\n return minDist;\n }\n }]);\n\n return WorleyNoise;\n}();\n\nvar euclidean = function euclidean(dx, dy, dz) {\n return dx * dx + dy * dy + dz * dz;\n};\n\nvar manhattan = function manhattan(dx, dy, dz) {\n return Math.abs(dx) + Math.abs(dy) + Math.abs(dz);\n};\n\nvar _default = WorleyNoise;\nexports.default = _default;\n\n//# sourceURL=webpack://WorleyNoise/./src/worley-noise.js?");
131 |
132 | /***/ })
133 |
134 | /******/ });
135 | });
--------------------------------------------------------------------------------
/examples/advanced.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Advanced example
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/examples/anim.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Animation example
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/examples/basic.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Basic example
6 |
7 |
8 |
9 |
10 |
11 |
12 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/img/e1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsoltc/worley-noise/6410c3cc4bf1a7247e31ff6f76dd99821b8ae16c/img/e1.png
--------------------------------------------------------------------------------
/img/e2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsoltc/worley-noise/6410c3cc4bf1a7247e31ff6f76dd99821b8ae16c/img/e2.png
--------------------------------------------------------------------------------
/img/e3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsoltc/worley-noise/6410c3cc4bf1a7247e31ff6f76dd99821b8ae16c/img/e3.png
--------------------------------------------------------------------------------
/img/m1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsoltc/worley-noise/6410c3cc4bf1a7247e31ff6f76dd99821b8ae16c/img/m1.png
--------------------------------------------------------------------------------
/img/m2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsoltc/worley-noise/6410c3cc4bf1a7247e31ff6f76dd99821b8ae16c/img/m2.png
--------------------------------------------------------------------------------
/img/noise3D.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zsoltc/worley-noise/6410c3cc4bf1a7247e31ff6f76dd99821b8ae16c/img/noise3D.gif
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "worley-noise",
3 | "version": "2.0.0",
4 | "description": "Worley noise in JavaScript",
5 | "main": "dist/worley-noise.js",
6 | "files": [
7 | "src/*"
8 | ],
9 | "directories": {
10 | "example": "examples"
11 | },
12 | "scripts": {
13 | "dev": "webpack --mode development --watch",
14 | "build": "webpack --mode production"
15 | },
16 | "repository": {
17 | "type": "git",
18 | "url": "git+https://github.com/zsoltc/worley-noise.git"
19 | },
20 | "keywords": [
21 | "worley",
22 | "noise",
23 | "javascript"
24 | ],
25 | "author": "Zsolt Czinege",
26 | "license": "MIT",
27 | "bugs": {
28 | "url": "https://github.com/zsoltc/worley-noise/issues"
29 | },
30 | "homepage": "https://github.com/zsoltc/worley-noise#readme",
31 | "devDependencies": {
32 | "@babel/core": "^7.2.2",
33 | "@babel/plugin-transform-modules-commonjs": "^7.2.0",
34 | "@babel/preset-env": "^7.3.1",
35 | "babel-loader": "^8.0.5",
36 | "webpack": "^4.29.0",
37 | "webpack-cli": "^3.2.1"
38 | },
39 | "dependencies": {
40 | "alea": "^1.0.0"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import WorleyNoise from './worley-noise';
2 |
3 |
4 | module.exports = WorleyNoise;
5 |
--------------------------------------------------------------------------------
/src/worley-noise.js:
--------------------------------------------------------------------------------
1 | import Alea from 'alea';
2 |
3 |
4 | class WorleyNoise {
5 | constructor(config) {
6 | config = config || {};
7 | if (config.dim !== 2 && config.dim !== 3 && config.dim !== undefined)
8 | throw '"dim" can be 2 or 3';
9 |
10 | this._dim = config.dim || 2;
11 | this._rng = new Alea(config.seed || Math.random());
12 | this._points = [];
13 |
14 | for (let i = 0; i < config.numPoints; i++) {
15 | this._points.push({
16 | x: this._rng(),
17 | y: this._rng(),
18 | z: this._rng(),
19 | });
20 | }
21 | }
22 |
23 | addPoint(coord) {
24 | this._points.push(coord);
25 | }
26 |
27 | getEuclidean(coord, k) {
28 | return Math.sqrt(this._calculateValue(coord, k, euclidean));
29 | }
30 |
31 | getManhattan(coord, k) {
32 | return this._calculateValue(coord, k, manhattan);
33 | }
34 |
35 | renderImage(resolution, config) {
36 | config = config || {};
37 | const step = 1 / (resolution - 1);
38 | const img = [];
39 | const callback = config.callback || ((e, m) => e(1));
40 | let x, y;
41 |
42 | const e = k => Math.sqrt(this._calculateValue({
43 | x: x * step,
44 | y: y * step,
45 | z: config.z || 0,
46 | }, k, euclidean));
47 |
48 | const m = k => this._calculateValue({
49 | x: x * step,
50 | y: y * step,
51 | z: config.z || 0,
52 | }, k, manhattan);
53 |
54 | for (y = 0; y < resolution; ++y) {
55 | for (x = 0; x < resolution; ++x) {
56 | img[y * resolution + x] = callback(e, m);
57 | }
58 | }
59 |
60 | if (!config.normalize)
61 | return img;
62 |
63 | let min = Number.POSITIVE_INFINITY;
64 | let max = Number.NEGATIVE_INFINITY;
65 |
66 | img.forEach(v => {
67 | min = Math.min(min, v);
68 | max = Math.max(max, v);
69 | });
70 |
71 | let scale = 1 / (max - min);
72 | return img.map(v => (v - min) * scale);
73 | }
74 |
75 | _calculateValue(coord, k, distFn) {
76 | let minDist;
77 | this._points.forEach(p => { p.selected = false; });
78 |
79 | for (let j = 0; j < k; ++j) {
80 | let minIdx;
81 | minDist = Number.POSITIVE_INFINITY;
82 |
83 | for (let i = 0; i < this._points.length; ++i) {
84 | const p = this._points[i];
85 | const dz = this._dim === 2 ? 0 : coord.z - p.z;
86 | const dist = distFn(coord.x - p.x, coord.y - p.y, dz);
87 |
88 | if (dist < minDist && !p.selected) {
89 | minDist = dist;
90 | minIdx = i;
91 | }
92 | }
93 |
94 | this._points[minIdx].selected = true;
95 | }
96 |
97 | return minDist;
98 | }
99 | }
100 |
101 | const euclidean = (dx, dy, dz) => dx * dx + dy * dy + dz * dz;
102 | const manhattan = (dx, dy, dz) => Math.abs(dx) + Math.abs(dy) + Math.abs(dz);
103 |
104 | export default WorleyNoise;
105 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 |
4 | module.exports = {
5 | entry: './src/index.js',
6 | output: {
7 | path: path.resolve(__dirname, 'dist'),
8 | filename: 'worley-noise.js',
9 | library: 'WorleyNoise',
10 | libraryTarget: 'umd',
11 | globalObject: 'typeof self !== "undefined" ? self : this',
12 | },
13 | module: {
14 | rules: [{
15 | test: /\.js$/,
16 | exclude: /node_modules/,
17 | use: {
18 | loader: 'babel-loader'
19 | }
20 | }]
21 | }
22 | };
23 |
--------------------------------------------------------------------------------