Generative Descent: Hallucinating a World and Sinking Through It
Inspired by Iron catastrophe on Wikipedia
Built with Three.js · ShaderMaterial · InstancedMesh · EffectComposer (UnrealBloomPass) · Web Audio API · fal.ai (Flux, TripoSR)
Techniques Gaussian Splat Rendering · Additive Blending · Bloom · Vignette
Direction Recreate planetary differentiation as an interactive scroll — type a word, let AI dream a 3D mesh, then descend through geological time as 18,000 splats sort by density
Result A generative AI pipeline turns your word into a Gaussian splat cloud that transforms from cool blue minerals to white-hot molten iron as you scroll, with dense splats sinking and light ones floating
The Story
4.5 billion years ago, the early Earth was a homogeneous ball of rock and metal. Then something shifted. Dense molten iron began sinking through lighter silicates. The sinking released gravitational energy as heat. The heat melted more rock. More iron sank. A runaway process — the iron catastrophe.
It’s called a catastrophe, but it was actually genesis. Without it: no iron core, no magnetic field, no atmosphere, no life. The most important event in Earth’s history was heavy stuff falling through light stuff.
We wanted to make that process interactive, and we wanted AI to dream the world you fall through.
The Take
The Catastrophe is a generative descent. You type a word. FAL.ai’s Flux model imagines it as an image, then TripoSR converts that image into a 3D mesh. We extract the mesh vertices, scatter 18,000 Gaussian splats across the shape, and you scroll to descend through geological time. Cool blue minerals warm to amber, then to molten orange-red, then to white-hot iron at the core. Dense splats sink. Light splats float. At the center, the particles collapse into your word.
The Tech
AI Pipeline: Text → Image → 3D
The generation chain runs through a Cloudflare Pages Function that proxies two FAL.ai endpoints:
- Flux Dev (
fal-ai/flux/dev) — text-to-image, generates a 1024x1024 visual interpretation of the user’s word - TripoSR (
fal-ai/triposr) — image-to-3D, converts the image into a GLB mesh withmc_resolution: 256
The function chains these calls server-side so the FAL API key never touches the client. A pre-generated fallback GLB (an obsidian volcanic landscape) loads when the API is unavailable.
Gaussian Splat Rendering
We render 18,000 camera-facing quads using THREE.InstancedMesh with a custom ShaderMaterial. Each quad acts as a Gaussian splat:
- Vertex shader: Billboard orientation (quad always faces camera), dual-target positioning for the text morph (
mix(scenePos, textTarget, uMorphProgress)), scale growth with depth - Fragment shader: Gaussian alpha falloff (
exp(-dist² * 4)) from quad center, depth-dependent color transformation - Blending:
THREE.AdditiveBlendingwithdepthWrite: false— splats accumulate light like volumetric gas
Each splat carries instance attributes: position (from GLB vertices), base color (cool blue-gray minerals), density (random 0-1), and scale.
Geological Color Transformation
The vertex shader drives a four-phase color shift based on the uDepth uniform (0 = surface, 1 = core):
- Phase 1 (0-30%): Cool mineral brightening — the blue-cyan base colors intensify
- Phase 2 (25-60%): Warm shift — colors lerp toward amber/orange (
vec3(0.7, 0.35, 0.1)) - Phase 3 (55-85%): Molten iron — bright orange-red (
vec3(1.0, 0.45, 0.12)), dense splats glow brighter - Phase 4 (80-100%): White-hot core — lerp toward
vec3(1.0, 0.85, 0.65)
A saturationControl multiplier kicks in above 60% depth to prevent additive blending from washing out to pure white.
Density Differentiation Physics
Each splat has a random density value (0-1). Once scroll depth passes 25%, a differentiation force activates:
force = (density - 0.4) * gravity * diffProgress
velocity += force * delta
velocity *= 0.97 // drag
yOffset += velocity * delta
Splats above neutral buoyancy (0.4) sink. Below it, they float. The result: heavy iron separates downward, light silicates drift upward. The mixed cloud sorts itself over the scroll journey — the actual physics of planetary differentiation, simplified to a spring-damper per particle.
Scroll-Driven Camera
The camera dollies from z=12 to z=6 with a slow orbit (sin(elapsed * 0.04)) for visual interest. Field of view widens from 50° to 85° — the Hitchcock dolly zoom effect that makes the descent feel like falling. Bloom strength and threshold shift with depth: subtle glow at the surface, intense emission at the core.
Post-Processing Stack
- UnrealBloomPass — strength tracks depth (0.15 at surface → 0.55 at core), threshold drops from 0.82 to 0.70
- Custom grain/vignette pass — film grain for texture, vignette that tightens with depth, warm color shift (
color.r += depth * 0.03)
Audio
Four sine oscillators at harmonic intervals (440, 660, 880, 1100 Hz) descend with scroll depth: freq = baseFreq * (1 - depth * 0.7). Volume peaks mid-descent and fades at the core. The result: a descending harmonic drone that signals increasing depth.
The Hardest Part
Getting additive blending to look good across the full brightness range. At the surface, 18,000 blue splats with additive blending produce a bright but structured form. At the core, the same splats with warm colors and increased bloom become a supernova. We spent most of the iteration time on the saturation control curve — a simple multiplier (1.0 - smoothstep(0.6, 1.0, depth) * 0.45) that dims the vertex shader output at extreme depth, keeping the molten iron visible without blowing out.
The other challenge: getting the GLB mesh from TripoSR to read as a meaningful shape. TripoSR meshes are small (~1 unit) with no vertex colors. We scale them 7x and use the vertex positions purely as a spatial distribution template — the colors come entirely from the shader’s geological transformation.