A field of cubes in Three.js

The raymarched scene is raw WebGL with no dependencies. For anything with real geometry, I’d rather use a library. This one uses Three.js, loaded straight from a CDN.

576 boxes, one draw call. Drag to orbit.

One mesh, many copies

Drawing 576 separate boxes would take 576 draw calls. An InstancedMesh draws them all in one: the box geometry is uploaded once, and each copy gets its own transform and colour.

const mesh = new THREE.InstancedMesh(
  new THREE.BoxGeometry(SIZE, 1, SIZE),
  new THREE.MeshStandardMaterial({ roughness: 0.6 }),
  N * N,
);

Every frame, each box is scaled to its height and lifted so it stands on the floor:

matrix.makeScale(1, h, 1).setPosition(x, h / 2, z);
mesh.setMatrixAt(k, matrix);

The box is one unit tall and centred on the origin, so scaling it by h and lifting it by h / 2 puts its base at zero.

Two waves

Each box’s height is two waves added together: a ripple that spreads out from the centre and dies away with distance, and a slow swell drifting across the grid. Colour follows height, from a pale tint of the theme’s accent colour up to the accent itself.

Loading it

The module starts with an import from jsDelivr, so there’s no build step and nothing to install:

import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.186.0/build/three.module.min.js';

Pinning the version keeps the post working when Three.js changes its API, which it does fairly often.