DEV Community

prodiamadmin
prodiamadmin

Posted on

How we built a diamond's 3-billion-year journey in WebGL (Three.js + GSAP)

We open-sourced a scroll-driven WebGL piece that traces a single natural diamond from its birth about 150 km down in the mantle, across three billion years, up to a finished ring. As you scroll, the stone is cut in front of you, from a rough octahedral crystal into a round brilliant.

Live: https://www.prodiam.co.za/oldest/
Source (MIT): https://github.com/prodiamadmin/deep-time-diamond

Here is how it is built.

Stack

  • Three.js r184 for the diamond and all 3D
  • GSAP + ScrollTrigger so every animation is driven by scroll position
  • Lenis for inertial smooth-scroll that the timeline reads from
  • HTML5 audio for the voiceover and ambient bed

The diamond is procedural, not a model

There is no .glb. The brilliant is generated from rings of vertices: a table, a table ring, girdle top and bottom, and one culet point at the bottom, stitched into facets. Flat shading means each facet catches light on its own, like a real cut stone:

function makeBrilliant(N) {
  const rg = 1.0, rt = 0.56, ht = 0.36, gd = 0.05, pd = 0.92;
  const v = [0, ht, 0];                 // table center
  for (let k = 0; k < N; k++) {         // table ring
    const a = k / N * Math.PI * 2;
    v.push(Math.cos(a) * rt, ht, Math.sin(a) * rt);
  }
  // ...girdle top, girdle bottom...
  v.push(0, -(gd + pd), 0);             // culet
  // index facets, computeVertexNormals(), flatShading: true
}
Enter fullscreen mode Exit fullscreen mode

The cut is a single morph target

The rough raw crystal is a second set of vertex positions on the same geometry, an irregular octahedron (apex, a jittered wide equator, apex). It starts at full influence, so the very first thing you see is a raw stone:

geo.morphAttributes.position = [new THREE.Float32BufferAttribute(roughPos, 3)];
diamond.morphTargetInfluences = [1]; // 1 = fully rough
Enter fullscreen mode Exit fullscreen mode

During the cutting-bench scene, one GSAP tween drives that influence to 0 and turns the optics on at the same instant. That single tween is the entire rough-to-brilliant reveal:

tl.to(diamond.morphTargetInfluences, { 0: 0, duration: w, ease: 'power2.inOut' }, benchStart)
  .to(material, {
    roughness: 0, transmission: 1, dispersion: 1.25,
    clearcoat: 1, thickness: 2, envMapIntensity: 2.2,
    duration: w, ease: 'power2.inOut'
  }, benchStart);
Enter fullscreen mode Exit fullscreen mode

Fire, without a path tracer

The material is a MeshPhysicalMaterial with ior: 2.42, the real refractive index of diamond, plus transmission and dispersion for the rainbow fire. Reflections come from a PMREM-prefiltered RoomEnvironment, and the canvas is transparent (alpha: true) so the 3D floats over DOM era-art and film. Tone mapping is ACES Filmic. It holds 60fps on a phone and still reads as a diamond.

Scroll is the timeline

One GSAP master timeline owns everything: camera dolly, rotation, era cross-fades, copy, and the cut. ScrollTrigger scrubs it, and Lenis feeds scroll into the GSAP ticker so the scrub stays smooth:

const lenis = new Lenis({ lerp: 0.08, smoothWheel: !reduced });
lenis.on('scroll', ScrollTrigger.update);
gsap.ticker.add((t) => lenis.raf(t * 1000));
Enter fullscreen mode Exit fullscreen mode

Each act gets a weight, not a fixed height. The deep-time montage (older than the pyramids, older than the first flower) gets about three times the scroll room of any other beat so it actually lands:

const WEIGHTS = [1.1, 3.6, 1.4, 1.4, 1.3, 1.7, 1.5];
scrollEl.style.height = WEIGHTS.reduce((a, b) => a + b, 0) * 100 + 'vh';
Enter fullscreen mode Exit fullscreen mode

Performance and accessibility

  • Only the active scene's <video> plays; the rest are paused as you scroll past.
  • devicePixelRatio is capped at 2.
  • prefers-reduced-motion drops the smooth-scroll and the scrub, degrading to plain page scroll.
  • A ?static flag exposes window.__shot(progress) to render any single frame on demand, which made deterministic QA screenshots trivial.

Why

ProDiam is a natural-diamond cutting house in Bedfordview, South Africa (https://www.prodiam.co.za). They buy rough, cut it in-house, and sell the finished stone, so we wanted to show the part nobody usually sees: the three billion years before the ring.

It is MIT-licensed. Fork it, tear out the diamond, and point the same scroll engine at your own story. Feedback welcome, especially on the dispersion look and the scroll performance.

Top comments (0)