Projects

Project · Live

Gravitational Well 3D

An interactive 3D visualization of General Relativity. Most educational material represents spacetime as a flat 2D rubber sheet — which is wrong. Spacetime is volumetric, and gravity warps it from every angle. This simulation shows that, with a 3D grid deformed in real time by a GLSL vertex shader.

Gravitational Well 3D in action: a single planet at the center of a volumetric wireframe cube, its mass warping the grid lines radially from every direction. Control panel on the left shows divisions, radius, intensity, gravity presets, and particle controls.

Why I built this

Almost every illustration of gravity you've seen — the bowling ball on a stretched bedsheet, the planet sinking into a funnel — collapses a three-dimensional phenomenon onto a single plane. It biases the intuition toward thinking gravity "pulls down" into a hole.

In reality, spacetime isn't a sheet — it's a volumetric fabric extending in all directions. Mass warps it from every possible angle. I wanted a simulation that shows that honestly, where you can rotate around the well and see the curvature wrap around the body in 3D instead of dipping below it.

Features

  • 3D volumetric grid deformed in real time by a custom GLSL vertex shader.
  • Up to 8 simultaneous masses — each with independent position, radius, and color.
  • Gravity presets from the Moon (0.16 G) to a Neutron Star (extreme), plus a free intensity slider.
  • Gravitational waves — animated ripples in the spacetime fabric, à la Einstein 1916.
  • Test particles with motion trails that follow geodesics through curved space.
  • Scenario presets: Black Hole, Binary System, Triple System, Standard Well.
  • Adjustable grid resolution up to 60³ divisions, transparency control, starfield background, orbit camera, frosted-glass UI.

Stack

  • Three.js (WebGL) with custom GLSL shaders for the deformable cubic grid.
  • React 19 + TypeScript for the UI; Tailwind CSS 4 for styling.
  • Vite 6 for dev and build.
  • The entire simulation — UI, scene setup, animation loop, shaders — lives in a single self-contained src/App.tsx.

How the shader works

For each vertex of the grid, the shader computes the displacement caused by every active mass. Roughly:

base    = (G · mass²) / max(r, minR)²   // inverse-square law
base    = base / (1 + base)             // saturation
falloff = 1 / (1 + 0.015·r)             // gentle distance falloff
wave    = sin(r·0.5 − t·5) · e^(−r·0.02) · waveAmp

Each vertex is then pulled radially toward the mass by an amount proportional to base, clamped so it never enters the body's sphere, and projected back inside the cube boundary so the wireframe never escapes its bounding box. Up to MAX_MASSES = 8 bodies are summed per vertex via uniform arrays.

Honest caveats

  • This is a visual analogue, not a numerical relativity solver. The math is tuned for legibility, not physical accuracy.
  • Very high Divisions × many active masses can be expensive on integrated GPUs.
  • The project was scaffolded inside Google AI Studio, so the example env mentions GEMINI_API_KEY — but the current simulation does not actually call the Gemini API.

Status

Live in Google AI Studio. Source under Apache-2.0 at rafaehlers/Gravitational-Well-3D. First public release: February 2026.