89 lines
2.1 KiB
JavaScript
89 lines
2.1 KiB
JavaScript
import seedrandom from 'seedrandom'
|
|
|
|
class PerlinNoise {
|
|
constructor (rand = Math.random) {
|
|
let perm = new Int8Array(257)
|
|
|
|
for (let i = 0; i < 256; i++) {
|
|
perm[i] = i & 1 ? 1 : -1
|
|
}
|
|
|
|
for (let i = 0; i < 256; i++) {
|
|
let j = rand() * 4294967296 & 255
|
|
|
|
var _ref = [perm[j], perm[i]]
|
|
perm[i] = _ref[0]
|
|
perm[j] = _ref[1]
|
|
}
|
|
perm[256] = perm[0]
|
|
|
|
function noise1d (x) {
|
|
let x0 = x | 0
|
|
let x1 = x - x0
|
|
let xi = x0 & 255
|
|
let fx = (3 - 2 * x1) * x1 * x1
|
|
let a = x1 * perm[xi]
|
|
let b = (x1 - 1) * perm[xi + 1]
|
|
|
|
return a + fx * (b - a)
|
|
}
|
|
|
|
function noise (x) {
|
|
let sum = 0
|
|
|
|
sum += (1 + noise1d(x)) * 0.25
|
|
sum += (1 + noise1d(x * 2)) * 0.125
|
|
sum += (1 + noise1d(x * 4)) * 0.0625
|
|
sum += (1 + noise1d(x * 8)) * 0.03125
|
|
|
|
return sum
|
|
}
|
|
|
|
this.noise = noise
|
|
}
|
|
}
|
|
|
|
class HeightMap {
|
|
// amplitude - Controls the amount the height changes. The higher, the taller the hills.
|
|
// persistence - Controls details, value in [0,1]. Higher increases grain, lower increases smoothness.
|
|
// octaves - Number of noise layers
|
|
// period - Distance above which we start to see similarities. The higher, the longer "hills" will be on a terrain.
|
|
// lacunarity - Controls period change across octaves. 2 is usually a good value to address all detail levels.
|
|
constructor (offsetY, seed, amplitude = 30, persistence = 0.5, octaves = 5, period = 80, lacunarity = 2) {
|
|
this.iy = offsetY
|
|
this.seed = seed
|
|
|
|
this.noise = new PerlinNoise(seedrandom(seed))
|
|
|
|
this.amplitude = amplitude
|
|
this.period = period
|
|
this.lacunarity = lacunarity
|
|
this.octaves = octaves
|
|
this.persistence = persistence
|
|
}
|
|
|
|
getNoise (zx) {
|
|
let x = zx / this.period
|
|
|
|
let amp = 1.0
|
|
let max = 1.0
|
|
let sum = this.noise.noise(x)
|
|
|
|
let i = 0
|
|
while (++i < this.octaves) {
|
|
x *= this.lacunarity
|
|
amp *= this.persistence
|
|
max += amp
|
|
sum += this.noise.noise(x) * amp
|
|
}
|
|
|
|
return sum / max
|
|
}
|
|
|
|
getHeight (x) {
|
|
return this.getNoise(x) * this.amplitude + this.iy
|
|
}
|
|
}
|
|
|
|
export { HeightMap }
|