Source


const CELLS = 100;
let input;

let lodSlider;

let falloffSlider;

let terrain = Array(CELLS);
let angle = 0;

function setup() {
  createCanvas(600, 600, WEBGL);
  perspective(PI/3, width/height, 0.1, 300);
  //noLoop();
  noStroke();

  for (let i = 0; i < CELLS; i++){
    terrain[i] = Array(CELLS);
  }

  input = createInput('.06');
  input.position(10, height+20);
  input.changed(update);

  lodSlider = createSlider(1, 16, 4, 1);
  lodSlider.position(10, height+40);
  lodSlider.changed(update);

  falloffSlider = createSlider(0, 1, .5, .01);
  falloffSlider.position(10, height+60);
  falloffSlider.changed(update);

  update();
}

function draw() {
  background(0);
  stroke(255);
  noFill();

  
  camera(0, CELLS*.8, 35, 
          0, 0, 0, 
          0, 1, 0);
  rotateZ(angle);
  angle+=0.01;
  const cx = CELLS/2;
  const cy = CELLS/2;

  for (let j = 0; j < CELLS-1; j++){
    beginShape(TRIANGLE_STRIP);
    for (let i = 0; i < CELLS; i++){
      vertex(cx - i, cy - j, terrain[i][j]);
      vertex(cx - i, cy - (j+1), terrain[i][j+1]);
    }
    endShape();
  }



}


function update(){
  terrain = growTerrain(terrain, 
      parseFloat(input.value()), 
      lodSlider.value(),
      falloffSlider.value(), 
      20);
  redraw();
}


function growTerrain(terrain, scale, lod, falloff, maxHeight){
  noiseDetail(lod, falloff);
  let s = maxHeight;
  let b = 0;
  for (let i = 0; i < terrain.length; i++){
    for (let j = 0; j < terrain[i].length; j++){
      terrain[i][j] = noise(i*scale, j*scale) * maxHeight;
      s = min(s, terrain[i][j]);
      b = max(b, terrain[i][j]);
    }
  }
  print(s, b);
  return terrain;
}