73 lines
1.8 KiB
JavaScript
73 lines
1.8 KiB
JavaScript
import OpenSimplexNoise from 'open-simplex-noise'
|
|
import { vec3 } from 'gl-matrix'
|
|
import Resource from '../../resource'
|
|
|
|
class HeightMap {
|
|
constructor (size) {
|
|
this.size = size
|
|
}
|
|
|
|
static async fromFile (file, amplitude) {
|
|
let img = await Resource.loadImage(file)
|
|
if (img.width / img.height !== 1) throw new Error('Height Map needs to be of 1:1 aspect ratio.')
|
|
|
|
let hmap = new HeightMap(img.width)
|
|
let sampler = Resource.imageToSampler(img)
|
|
|
|
for (let x = 0; x < img.width; x++) {
|
|
for (let y = 0; y < img.width; y++) {
|
|
hmap['h' + x + ';' + y] = (sampler(x, y)[0] / 255 * 2 - 1) * amplitude
|
|
}
|
|
}
|
|
|
|
sampler = null
|
|
|
|
return hmap
|
|
}
|
|
|
|
getHeight (x, y) {
|
|
if (x > this.size || y > this.size || x < 0 || y < 0) return 0
|
|
if (!this['h' + x + ';' + y]) return 0
|
|
return this['h' + x + ';' + y]
|
|
}
|
|
|
|
getNormal (x, y) {
|
|
let hL = this.getHeight(x - 1, y)
|
|
let hR = this.getHeight(x + 1, y)
|
|
let hD = this.getHeight(x, y - 1)
|
|
let hU = this.getHeight(x, y + 1)
|
|
let normal = vec3.fromValues(hL - hR, 2.0, hD - hU)
|
|
vec3.normalize(normal, normal)
|
|
return normal
|
|
}
|
|
}
|
|
|
|
class SimplexHeightMap extends HeightMap {
|
|
constructor (offsetX, offsetY, size, seed) {
|
|
super(size)
|
|
this.ix = offsetX
|
|
this.iy = offsetY
|
|
this.seed = seed
|
|
|
|
this.osn = new OpenSimplexNoise(seed)
|
|
}
|
|
|
|
getNoise (relX, relY) {
|
|
let x = ((this.ix * this.size) + relX) / this.size - 0.5
|
|
let y = ((this.iy * this.size) + relY) / this.size - 0.5
|
|
|
|
let total = this.osn.noise2D(2 * x, 2 * y) +
|
|
0.5 * this.osn.noise2D(4 * x, 4 * y) +
|
|
0.25 * this.osn.noise2D(2 * x, 2 * y)
|
|
|
|
total *= 10
|
|
return total
|
|
}
|
|
|
|
getHeight (x, y) {
|
|
return this.getNoise(x, y)
|
|
}
|
|
}
|
|
|
|
export { HeightMap, SimplexHeightMap }
|