PRJ-002 · 3d-spatial
Amman Echoes
GJU Media Lab × Goethe-Institut Amman · Creative Technologist — audio analysis, visuals, installation build · 2025
An audio-reactive installation that turns field recordings of Amman's seven hills into a living light topography — projected on a 4-meter wall for a two-week exhibition.
Core Philosophy
Amman is a city you hear before you see: the overlapping adhan across valleys, taxi horns, staircase footsteps, evening swifts. The installation treats sound as terrain — each hill's recording displaces a ridge of the mesh, so the city's noise literally shapes its silhouette.
I wanted visitors to recognize their own streets in an abstraction. The mapping had to be legible, not clever: loudness lifts the terrain, spectral brightness sharpens the light. Anyone could stand there for thirty seconds and understand the rule — then spend ten minutes feeling it.
Outcomes
- Ran 11 hours/day for 14 days without a restart
- ~2,300 exhibition visitors; featured in the institute's yearbook
- Frame budget held at 16.6ms on a mid-range projection PC
Deliverables
- Real-time audio-reactive visual engine
- Field-recording corpus & FFT feature extraction
- Installation hardware setup & show control
Technical Anatomy
Audio feature extraction
Seven simultaneous field-recording stems run through an AnalyserNode each. Per frame I extract RMS energy and spectral centroid, smooth them with a one-pole filter, and hand a 14-float uniform block to the shader.
const rms = Math.sqrt(freq.reduce((s, v) => s + v * v, 0) / freq.length);
smoothed[i] += (rms - smoothed[i]) * 0.08; // one-pole, ~200ms settle
Terrain displacement shader
The wall is a 512×256 plane displaced in the vertex shader. Each hill owns a Gaussian falloff region; audio energy scales displacement inside it. Normals are recomputed analytically to keep lighting coherent.
float ridge = 0.0;
for (int i = 0; i < 7; i++) {
float d = distance(uv, uHillCenter[i]);
ridge += uEnergy[i] * exp(-d * d / (2.0 * uSigma * uSigma));
}
pos.z += ridge * uAmplitude;
Show-control hardening
An exhibition can't crash. A watchdog restarts the render context on WebGL context-loss, audio decoding is preloaded and looped from memory, and a kiosk script recovers the whole machine on power failure.