UNPKG

value-noise-js

Version:

A light and simple way to generate 1D, 2D, and 3D value noise in javascript.

94 lines 4.67 kB
// src/value-noise.ts var ValueNoise = class { constructor(seed, length = 32, type = "cosine") { this.seed = seed; this.length = length; this.type = type; this.count = 0; this.n = []; this.lerp = (x, y, a) => x * (1 - a) + y * a; this.cosFade = (t, amplitude = 2, offset = 0.5) => offset - Math.cos(t * Math.PI) / amplitude; this.perlinFade = (t) => ((6 * t - 15) * t + 10) * t * t * t; this.$seed = seed ? seed : this.generateString(32); this.roots = this.cyrb128(this.$seed); this.len = Math.floor(length) == 0 ? 32 : Math.floor(length) < 8 ? 8 : 2 ** Math.round(Math.log2(Math.sqrt(Math.floor(length > 512 ? 512 : length) ** 2))); this.lenMax = this.len ** 2; this.p = new Uint32Array(new ArrayBuffer(this.lenMax * 8)); this.fade = type == "perlin" ? this.perlinFade : this.cosFade; this.genPermutation(); } refresh(seed) { this.$seed = seed ? seed : this.generateString(32); this.count = seed ? 0 : this.count++; this.roots = this.cyrb128(this.$seed); this.p = new Uint32Array(new ArrayBuffer(this.lenMax * 8)); this.n = []; this.genPermutation(); } genPermutation() { let rand = this.mulberry32(this.roots[0]); let shuffle = this.mulberry32(this.roots[this.count & 3]); for (let i = 0; i < this.lenMax; i++) { let r = this.lerp(0, 1, this.cosFade(rand())); this.n.push(r); this.p[i] = i; } for (let i = this.p.length / 2 - 1; i > 0; i--) { let r = Math.round(shuffle() * (this.p.length / 2 - 1)), iV = this.p[i]; this.p[i] = this.p[r]; this.p[r] = iV; } for (let i of this.p) { this.p[i + this.p.length / 2] = this.p[i]; } } evalX(x) { let min = Math.floor(x % this.lenMax), t = this.fade(x - min), max = min == this.lenMax - 1 ? 0 : min++; return this.lerp(this.n[min], this.n[max], t); } evalXY(x, y) { let iX = Math.floor(x), iY = Math.floor(y), tX = this.fade(x - iX), tY = this.fade(y - iY), iX0 = iX & this.lenMax - 1, iY0 = iY & this.lenMax - 1, iX1 = iX0 + 1 & this.lenMax - 1, iY1 = iY0 + 1 & this.lenMax - 1, c00 = this.n[this.p[this.p[iX0] + iY0]], c10 = this.n[this.p[this.p[iX1] + iY0]], c01 = this.n[this.p[this.p[iX0] + iY1]], c11 = this.n[this.p[this.p[iX1] + iY1]], evalX0 = this.lerp(c00, c10, tX), evalX1 = this.lerp(c01, c11, tX), evalXY = this.lerp(evalX0, evalX1, tY); return evalXY; } evalXYZ(x, y, z) { let iX = Math.floor(x) & this.lenMax - 1, iY = Math.floor(y) & this.lenMax - 1, iZ = Math.floor(z) & this.lenMax - 1, tX = this.fade(x - Math.floor(x)), tY = this.fade(y - Math.floor(y)), tZ = this.fade(z - Math.floor(z)), iXY0 = this.p[iX] + iY, iXY0Z0 = this.p[iXY0] + iZ, iXY0Z1 = this.p[iXY0 + 1] + iZ, iXY1 = this.p[iX + 1] + iY, iXY1Z0 = this.p[iXY1] + iZ, iXY1Z1 = this.p[iXY1 + 1] + iZ, c000 = this.n[this.p[iXY0Z0]], c010 = this.n[this.p[iXY1Z0]], c001 = this.n[this.p[iXY0Z1]], c011 = this.n[this.p[iXY1Z1]], c100 = this.n[this.p[iXY0Z0 + 1]], c110 = this.n[this.p[iXY1Z0 + 1]], c101 = this.n[this.p[iXY0Z1 + 1]], c111 = this.n[this.p[iXY1Z1 + 1]], evalX00 = this.lerp(c000, c010, tX), evalX01 = this.lerp(c001, c011, tX), evalXY0 = this.lerp(evalX00, evalX01, tY), evalX10 = this.lerp(c100, c110, tX), evalX11 = this.lerp(c101, c111, tX), evalXY1 = this.lerp(evalX10, evalX11, tY), evalXYZ = this.lerp(evalXY0, evalXY1, tZ); return evalXYZ; } cyrb128(str) { let h1 = 1779033703, h2 = 3144134277, h3 = 1013904242, h4 = 2773480762; for (let i = 0, k; i < str.length; i++) { k = str.charCodeAt(i); h1 = h2 ^ Math.imul(h1 ^ k, 597399067); h2 = h3 ^ Math.imul(h2 ^ k, 2869860233); h3 = h4 ^ Math.imul(h3 ^ k, 951274213); h4 = h1 ^ Math.imul(h4 ^ k, 2716044179); } h1 = Math.imul(h3 ^ h1 >>> 18, 597399067); h2 = Math.imul(h4 ^ h2 >>> 22, 2869860233); h3 = Math.imul(h1 ^ h3 >>> 17, 951274213); h4 = Math.imul(h2 ^ h4 >>> 19, 2716044179); h1 ^= h2 ^ h3 ^ h4, h2 ^= h1, h3 ^= h1, h4 ^= h1; return [h1 >>> 0, h2 >>> 0, h3 >>> 0, h4 >>> 0]; } generateString(length) { const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; let result = ""; const charactersLength = characters.length; for (let i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; } mulberry32(a) { return () => { var t = a += 1831565813; t = Math.imul(t ^ t >>> 15, t | 1); t ^= t + Math.imul(t ^ t >>> 7, t | 61); return ((t ^ t >>> 14) >>> 0) / 4294967296; }; } }; export { ValueNoise }; //# sourceMappingURL=value-noise.mjs.map