html, body {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  background: #292a33;
  overflow: hidden;
}
const minSize = 1;
const maxSize = 256; // 2の倍数にする
const space = 2;
let noise2d;

function setup() {
  createCanvas(windowWidth, windowHeight);
  rectMode(CENTER);
  noStroke();

  noise2d = [];
  for (let i = 0; i < maxSize; i++) {
    noise2d[i] = [];
  }

  generateHeightmap(0, 0, maxSize, random(), random(), random(), random());

  for (let y = 0; y < maxSize; y++) {
    for (let x = 0; x < maxSize; x++) {
      const v = noise2d[y][x];
      if (v <= 0.325) {
        fill("#5e539e");
      } else if (v <= 0.5) {
        fill("#5584c5");
      } else if (v <= 0.53125) {
        fill("#7ac1a5");
      } else if (v <= 0.5625) {
        fill("#a2d7a4");
      } else if (v <= 0.6875) {
        fill("#d3d599");
      } else if (v <= 0.875) {
        fill("#808080");
      } else {
        fill("#fff");
      }

      rect(x * space, y * space, space, space);
    }
  }
}

function generateHeightmap(x, y, size, tl, tr, bl, br) {
  if (size === minSize) {
    const value = (tl + tr + bl + br) / 4;
    noise2d[y][x] = value;
  } else {
    let midPoint = (tl + tr + bl + br) / 4 + getRandomHeight(size);
    midPoint = constrain(midPoint, 0, 1);
    const top = (tl + tr) / 2;
    const bottom = (bl + br) / 2;
    const left = (tl + bl) / 2;
    const right = (tr + br) / 2;

    size /= 2;
    generateHeightmap(x, y, size, tl, top, left, midPoint);
    generateHeightmap(x + size, y, size, top, tr, midPoint, right);
    generateHeightmap(x, y + size, size, left, midPoint, bl, bottom);
    generateHeightmap(x + size, y + size, size, midPoint, right, bottom, br);
  }
}

function getRandomHeight(value) {
  return ((random() - 0.5) * value) / maxSize;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.min.js