Terrain
by oisyn
HTML
Arrow keys to move, pgup/pgdn to change altitude<br>
<canvas width=1024 height=576 id=canvas></canvas><br>
<canvas width=256 height=256 id=heightmap></canvas><br>
CSS
canvas { border: 1px solid black; }
JavaScript
function mulberry32(seed)
{
return function()
{
seed = (seed + 0x9e3779b9) | 0; // the `| 0` coerces it into a 32-bit int
let z = seed;
z ^= z >>> 16;
z = Math.imul(z, 0x21f0aaad);
z ^= z >>> 15;
z = Math.imul(z, 0x735a2d97);
z ^= z >>> 15;
return (z >>> 0) / 0x100000000;
}
}
const TerrainSize = 2048, TerrainMask = TerrainSize - 1;
var heightmap = new Float32Array(TerrainSize * TerrainSize);
var colormap;
var sample = (x, y) => heightmap[((y & TerrainMask) * TerrainSize) + (x & TerrainMask)];
var samplemip = (x, y, m) => heightmap[((y & TerrainMask & (0xffffffff << m)) * TerrainSize) + (x & TerrainMask & (0xffffffff << m))];
var samplecolor = (x, y) => colormap[((y & TerrainMask) * TerrainSize) + (x & TerrainMask)];
var samplecolormip = (x, y, m) => colormap[((y & TerrainMask & (0xffffffff << m)) * TerrainSize) + (x & TerrainMask & (0xffffffff << m))];
let rnd = mulberry32(3);
var frnd = (min, max) => (max - min) * rnd() + min;
var clamp = (x, min, max) => Math.min(Math.max(x, min), max);
var rgb = (r, g, b) => r | (g << 8) | (b << 16) | 0xff000000;
const MaxHeight = 1024;//TerrainSize;
const WaterLevel = (MaxHeight / 2) | 0;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
const Width = canvas.width;
const Height = canvas.height;
const HalfWidth = Width / 2;
const HalfHeight = Height / 2;
var pixels = ctx.createImageData(Width, Height);
var pdata = new Uint32Array(pixels.data.buffer);
var hc = document.getElementById("heightmap");
hc.width = TerrainSize;
hc.height = TerrainSize;
hctx = hc.getContext("2d");
var himg = hctx.createImageData(TerrainSize, TerrainSize);
colormap = new Uint32Array(himg.data.buffer);
function put(x, y, v)
{
heightmap[y * TerrainSize + x] = v;
}
// Diamond-Square
heightmap[0] = MaxHeight / 2;
let rndrange = MaxHeight/2;
for (let w = TerrainSize / 2, l = 1; w >= 1; w >>= 1, l++)
{
const size = 2*w;
if (size <= MaxHeight)
rndrange *= 0.45;
//if (w == 2)
// rndrange *=...