Skip to main content
Home
three.js webgl history rome
WIP

Roma Aeterna

A scroll-driven narrative layering Roman history onto an interactive Three.js globe — from the Republic to Late Antiquity, one era at a time.

Concept
#

Rome’s 1,200-year arc — from a cluster of hilltop villages to the capital of a Mediterranean empire, then its slow fragmentation — is one of the great stories of human civilisation. Most visualisations of this history are either static maps or academic timelines. Roma Aeterna tries something different: a scroll-driven experience where the user moves through time, and the city transforms in front of them.

Technical approach
#

The core is a Three.js dotted globe — each dot represents a geographic coordinate, rendered as a particle — with Rome at centre. As the user scrolls, eras unlock:

  • 753 BCE — Seven Hills, the Tiber, Latin tribes
  • 509 BCE — the Republic takes shape; early road network emerges
  • 27 BCE — Augustan Rome; the Forum, the aqueducts, the legions’ reach
  • 117 CE — Trajan’s maximum extent; the empire at its peak
  • 476 CE — fragmentation; the Western provinces dissolve

Each transition uses a custom GSAP-driven interpolation between particle positions, so the city appears to literally grow and contract as you scroll.

Challenges
#

Rendering 50,000+ particles at 60fps on mobile required careful instancing:

const geometry = new THREE.BufferGeometry();
const positions = new Float32Array(PARTICLE_COUNT * 3);
// fill positions from geo dataset …
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));

const material = new THREE.PointsMaterial({
  size: 0.012,
  sizeAttenuation: true,
  color: 0xc4713c,   // terracotta
});

const points = new THREE.Points(geometry, material);
scene.add(points);

The scroll driver samples the user’s scroll position and maps it to a timeline value, which drives both the era label and the particle morph animation simultaneously.

Status
#

The globe and scroll-driven era transitions are working. Next milestone: adding annotated city overlays (roads, walls, aqueducts) as SVG layers composited over the WebGL canvas.