P.noiseEngines = {
'perlin': {
init: function () {
const {grad, size, rndEngine} = this;
let dist;
grad.length = 0;
for(let i = 0; i < size; i++) {
grad[i] = [(rndEngine.random() * 2) - 1, (rndEngine.random() * 2) - 1];
dist = Math.sqrt(grad[i][0] * grad[i][0] + grad[i][1] * grad[i][1]);
grad[i][0] /= dist;
grad[i][1] /= dist;
}
},
getNoiseValue: function (x, y) {
const {size, perm, grad, smoothing} = this;
let a, b, u, v;
let bx0 = Math.floor(x) % size,
bx1 = (bx0 + 1) % size;
let rx0 = x - Math.floor(x),
rx1 = rx0 - 1;
let by0 = Math.floor(y) % size,
by1 = (by0 + 1) % size;
let ry0 = y - Math.floor(y),
ry1 = ry0 - 1;
let i = perm[bx0],
j = perm[bx1];
let b00 = perm[i + by0],
b10 = perm[j + by0],
b01 = perm[i + by1],
b11 = perm[j + by1];
let sx = smoothing(rx0),
sy = smoothing(ry0);
u = rx0 * grad[b00][0] + ry0 * grad[b00][1];
v = rx1 * grad[b10][0] + ry0 * grad[b10][1];
a = interpolate(sx, u, v);
u = rx0 * grad[b01][0] + ry1 * grad[b01][1];
v = rx1 * grad[b11][0] + ry1 * grad[b11][1];
b = interpolate(sx, u, v);
return 0.5 * (1 + interpolate(sy, a, b));
},
},
'improved-perlin': {
init: λnull,
getNoiseValue: function (x, y) {
const {size, perm, permMod8, perlinGrad, smoothing} = this;
let a, b, u, v;
let bx0 = Math.floor(x) % size,
bx1 = (bx0 + 1) % size;
let rx0 = x - Math.floor(x),
rx1 = rx0 - 1;
let by0 = Math.floor(y) % size,
by1 = (by0 + 1) % size;
let ry0 = y - Math.floor(y),
ry1 = ry0 - 1;
let i = perm[bx0],
j = perm[bx1];
let b00 = permMod8[i + by0],
b10 = permMod8[j + by0],
b01 = permMod8[i + by1],
b11 = permMod8[j + by1];
let sx = smoothing(rx0),
sy = smoothing(ry0);
u = rx0 * perlinGrad[b00][0] + ry0 * perlinGrad[b00][1];
v = rx1 * perlinGrad[b10][0] + ry0 * perlinGrad[b10][1];
a = interpolate(sx, u, v);
u = rx0 * perlinGrad[b01][0] + ry1 * perlinGrad[b01][1];
v = rx1 * perlinGrad[b11][0] + ry1 * perlinGrad[b11][1];
b = interpolate(sx, u, v);
return 0.5 * (1 + interpolate(sy, a, b));
}
},
'simplex': {
init: λnull,
getNoiseValue: function (x, y) {
const getCornerNoise = function (cx, cy, gridPos) {
let calc = 0.5 - (cx * cx) - (cy * cy);
if (calc < 0) return 0;
let [gx, gy] = perlinGrad[gridPos];
return calc * calc * ((gx * cx) + (gy * cy));
};
const {simplexConstantF, simplexConstantG, simplexConstantDoubleG, size, perlinGrad, perm, permMod8} = this;
let summedCoordinates = (x + y) * simplexConstantF,
summedX = Math.floor(x + summedCoordinates),
summedY = Math.floor(y + summedCoordinates),
modifiedSummedCoordinates = (summedX + summedY) * simplexConstantG;
let cornerX = x - (summedX - modifiedSummedCoordinates),
cornerY = y - (summedY - modifiedSummedCoordinates);
let remainderX = summedX % size,
remainderY = summedY % size;
let pos = permMod8[remainderX + perm[remainderY]],
noise = getCornerNoise(cornerX, cornerY, pos);
pos = permMod8[remainderX + 1 + perm[remainderY + 1]]
noise += getCornerNoise((cornerX - 1 + simplexConstantDoubleG), (cornerY - 1 + simplexConstantDoubleG), pos);
let unitA = 0,
unitB = 1;
if (cornerX > cornerY) {
unitA = 1;
unitB = 0;
}
pos = permMod8[remainderX + unitA + perm[remainderY + unitB]];
noise += getCornerNoise((cornerX - unitA + simplexConstantG), (cornerY - unitB + simplexConstantG), pos);
return 0.5 + (35 * noise);
},
},
'value': {
init: function () {
const {values, size, rndEngine} = this;
values.length = 0;
for(let i = 0; i < size; i++) {
values[i] = values[i + size] = rndEngine.random();
}
},
getNoiseValue: function (x, y) {
const {values, size, perm, smoothing} = this;
let x0 = Math.floor(x) % size,
y0 = Math.floor(y) % size,
x1 = (x0 + 1) % size,
y1 = (y0 + 1) % size,
vx = x - Math.floor(x),
vy = y - Math.floor(y),
sx = smoothing(vx),
sy = smoothing(vy),
i = perm[x0],
j = perm[x1],
p00 = perm[i + y0],
p10 = perm[j + y0],
p01 = perm[i + y1],
p11 = perm[j + y1],
i1 = interpolate(sx, values[p00], values[p10]),
i2 = interpolate(sx, values[p01], values[p11]);
return interpolate(sy, i1, i2);
},
},
};