Skip to content

Instantly share code, notes, and snippets.

@hperantunes
Last active March 1, 2019 20:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hperantunes/5d8d3d0e6299d2124009325ed5fdcc9d to your computer and use it in GitHub Desktop.
Save hperantunes/5d8d3d0e6299d2124009325ed5fdcc9d to your computer and use it in GitHub Desktop.
/**
* 1D noise generator function.
* Inspired by https://codepen.io/Tobsta/post/procedural-generation-part-1-1d-perlin-noise
*
* @param {string} seed Initializes the pseudorandom number generator (default empty)
* @param {number} width Total number of points in the generated noise line (default 1)
* @param {number} amplitude Height of the wave (default 128)
* @param {number} wavelength Distance between the peaks of each wave (default 128)
* @param {number} octaves How many noise lines will be combined together (default 8)
* @param {number} divisor Number by witch each noise line will be divided (default 2)
* @param {number} offset Proportional offset applied to the amplitude (default -0.5)
* @return An array of points in a line
* @customfunction
*/
function NOISE(seed, width, amplitude, wavelength, octaves, divisor, offset) {
var seed = xmur3(seed !== undefined ? seed.toString() : ""),
width = width !== undefined ? width : 1
amp = amplitude !== undefined ? amplitude : 128,
wl = wavelength !== undefined ? wavelength : 128,
octaves = octaves !== undefined ? octaves : 8,
divisor = divisor !== undefined ? divisor : 2,
offset = offset !== undefined ? offset : -0.5;
var prng = sfc32(seed, offset);
var noise = generateNoise(prng, amp, wl, octaves, divisor, width);
return combineNoise(noise);
}
// hash function
function xmur3(str) {
for(var i = 0, h = 1779033703 ^ str.length; i < str.length; i++) {
h = (h ^ str.charCodeAt(i)) * 3432918353;
}
h = h << 13 | h >>> 19;
return function() {
h = (h ^ h >>> 16) * 2246822507;
h = (h ^ h >>> 13) * 3266489909;
return (h ^= h >>> 16) >>> 0;
}
}
// pseudo-random number generator
function sfc32(seed, offset) {
var a = seed();
var b = seed();
var c = seed();
var d = seed();
return function () {
a >>>= 0; b >>>= 0; c >>>= 0; d >>>= 0;
var t = (a + b) | 0;
a = b ^ b >>> 9;
b = c + (c << 3) | 0;
c = (c << 21 | c >>> 11);
d = d + 1 | 0;
t = t + d | 0;
c = c + t | 0;
return (t >>> 0) / 4294967296 + offset;
}
}
// cosine interpolation
function interpolate(pa, pb, px) {
var ft = px * Math.PI,
f = (1 - Math.cos(ft)) * 0.5;
return pa * (1 - f) + pb * f;
}
// 1D perlin line generator
function perlin(prng, amp, wl, width) {
this.x = 0;
this.amp = amp;
this.wl = wl;
this.fq = 1 / wl;
this.prng = prng;
this.a = this.prng();
this.b = this.prng();
this.pos = [];
while (this.x < width) {
if (this.x % this.wl === 0) {
this.a = this.b;
this.b = this.prng();
this.pos.push(this.a * this.amp);
} else {
this.pos.push(interpolate(this.a, this.b, (this.x % this.wl) / this.wl) * this.amp);
}
this.x++;
}
}
// octave generator
function generateNoise(prng, amp, wl, octaves, divisor, width) {
var result = [];
for (var i = 0; i < octaves; i++) {
result.push(new perlin(prng, amp, wl, width));
amp /= divisor;
wl /= divisor;
}
return result;
}
// combines octaves together
function combineNoise(pl) {
var result = {
pos: []
};
for (var i = 0, total = 0, j = 0; i < pl[0].pos.length; i++) {
total = 0;
for (j = 0; j < pl.length; j++) {
total += pl[j].pos[i];
}
result.pos.push(total);
}
return result.pos;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment