SERIENBEITRAG ·

Ein Schwarzes Loch atmet zur Musik

Wie ein Raymarcher Licht um ein Schwarzes Loch krümmt und zwei live erzeugte Ambient-Stücke Akkretionsscheibe, Sterne, Jets und Kamera dirigieren.

KONZEPT · UMSETZUNGOliver Röschner
LESEZEIT10 Minuten
BEREICHTECHNOLOGIE
Ein Schwarzes Loch vor einem dunklen Sternenfeld. Seine goldweiß leuchtende Akkretionsscheibe wird oberhalb und unterhalb des Schattens durch die Gravitation verzerrt; links oben erscheint das gebogene Bild einer Galaxie.
KI GENERIERTES ARTIKELBILD | OPERUS

Nach der Partikelmagier-Demo wollte ich herausfinden, ob sich Musik auch ohne Figur erzählen lässt. Keine Hände, die dirigieren, kein Drache als Höhepunkt – nur Licht, Zeit und ein Objekt, dem eigentlich nichts entkommt. So entstand die Ereignishorizont-Demo: ein Schwarzes Loch, dessen Akkretionsscheibe zur Musik pulsiert, dessen Umgebung sich im Build-up zusammenzieht und das am Ende selbst seine leuchtende Scheibe verschluckt.

Ein Schwarzes Loch vor einem dunklen Sternenfeld. Seine goldweiß leuchtende Akkretionsscheibe wird oberhalb und unterhalb des Schattens durch die Gravitation verzerrt; links oben erscheint das gebogene Bild einer Galaxie. INTERAKTIVE DEMO Der Ton startet nach der Trackauswahl
Ton einschalten, einen der beiden Ambient-Tracks wählen und den Auftakt einige Sekunden wirken lassen.

Der erste Eindruck ist bewusst ruhig. Vor dem Start sind fast nur Sterne zu sehen. Das Loch verrät sich durch ihre Verzerrung, bleibt aber noch eine Ahnung im Dunkeln. Erst mit der Musik zündet die Akkretionsscheibe von innen nach außen. Dunst, Funken und Galaxie erscheinen, während die Kamera aus der Ferne heranfährt. Die Szene beginnt nicht einfach – sie erwacht.

Licht wird zum eigentlichen Material

Ein Schwarzes Loch selbst ist nicht sichtbar. Sichtbar wird nur, was es mit seiner Umgebung macht. Deshalb besteht die zentrale Aufgabe dieser Demo nicht darin, eine dunkle Kugel zu zeichnen, sondern Lichtstrahlen glaubhaft um einen unsichtbaren Schatten zu führen.

Der Shader verfolgt deshalb für jeden Bildpunkt keine gerade Sichtlinie, sondern einen gekrümmten Weg. Ein Lichtstrahl kann die Scheibe dadurch aus ungewohnter Richtung treffen oder nur knapp am Schatten vorbeiziehen. So erscheint die Rückseite der Scheibe gleichzeitig über und unter dem Loch. Auch der dünne Photonenring ist keine aufgesetzte Grafik, sondern entsteht aus Strahlen, die den Schatten besonders eng umrunden.

Gekrümmte Lichtstrahlen im Fragment-Shader glsl
vec3 pos = uCamPos;
vec3 vel = rd;
float h2 = dot(cross(pos, vel), cross(pos, vel));

for (int i = 0; i < 400; i++) {
  if (float(i) >= uSteps) break;
  float r = length(pos);
  if (r < 1.0) { captured = true; break; }
  if (r > 60.0 && dot(pos, vel) > 0.0) break;

  float dt = clamp(r < 8.0 ? 0.06 * r : 0.1 * r - 0.32,
                   0.02, 3.0);
  vec3 prev = pos;
  vel += (-1.5 * h2 * pos / pow(r, 5.0)) * dt;
  pos += vel * dt;

  if (prev.y * pos.y < 0.0) {
    vec3 hit = mix(prev, pos, prev.y / (prev.y - pos.y));
    vec4 disk = diskSample(hit, normalize(vel), travel * uPix);
    col += (1.0 - alpha) * disk.rgb;
    alpha += (1.0 - alpha) * disk.a;
  }
}

Die Rechnung ist eine visuelle Näherung, kein astrophysikalischer Simulator. Entscheidend ist, dass sie die charakteristischen Bilder erzeugt: den schwarzen Schatten, die hochgezogene Rückseite der Scheibe und die verzerrte Galaxie dahinter.

Der Weg eines einzelnen Lichtstrahls

Three.js zeichnet zunächst nur ein bildschirmfüllendes Rechteck. Die eigentliche Szene entsteht im Fragment-Shader. JavaScript übergibt Kameraposition, Blickrichtung, Seitenverhältnis und Öffnungswinkel; daraus konstruiert jeder Bildpunkt seinen eigenen Startstrahl. Der Shader verwaltet dafür nur Position und Geschwindigkeit. Eine kleine Beschleunigung verändert die Richtung, anschließend rückt der Strahl um dt vor.

Der Weg endet auf drei Arten. Unterhalb von r = 1 gilt der Strahl als eingefangen. Jenseits von r = 60 darf er abbrechen, sobald er sich wieder vom Loch entfernt. Oder er hat genügend Licht gesammelt und erreicht eine Deckkraft von 0,97. So muss ein Strahl nicht länger gerechnet werden, als sein Ergebnis für das Bild noch einen Unterschied macht.

Die Scheibe ist keine Textur vor dem Schwarzen Loch. Der Shader erkennt, ob ein Schritt die Ebene y = 0 gekreuzt hat, interpoliert den genauen Treffpunkt und fragt dort Dichte, Temperatur, Doppler-Helligkeit und musikalische Wellen ab. Jet, Dunst und der einfallende Stern addieren unterwegs volumetrisches Licht. Nur wenn der Strahl nicht eingefangen wurde, füllt am Ende der Himmel den noch transparenten Rest. Dadurch entstehen Verdeckung, Linsenbild und leuchtende Atmosphäre innerhalb desselben Strahlwegs.

Rendering-Pipeline pro Bildpunkt text
Kamera → gekrümmter Lichtstrahl → Scheibe / Jet / Dunst / Stern
       → Ereignishorizont oder Himmel → Bloom und Farbkorrektur

Eine Scheibe, die nicht überall gleich leuchtet

Die Akkretionsscheibe besteht aus glühenden, rotierenden Bändern. Ihr Material bewegt sich auf der einen Seite auf die Kamera zu und auf der anderen von ihr weg. Ein vereinfachter Doppler-Effekt macht deshalb eine Hälfte heller und weißer, die andere wärmer und dunkler. Erst diese Asymmetrie gibt der Scheibe ihre räumliche Richtung.

Nahe am Loch werden die Schritte des Raymarchers kleiner. Weiter draußen darf er größere Sprünge machen. Auch in der Nähe der Jets und eines einfallenden Sterns rechnet der Shader feiner. Diese adaptive Schrittweite ist ein Kompromiss: genug Genauigkeit an den Stellen, die das Bild tragen, ohne jeden Strahl über die gesamte Strecke mit maximaler Auflösung zu verfolgen.

Über dem Raymarcher kreisen hunderte Funken nach innen. Sie werden immer schneller und verschwinden im Schatten. Anders als die Galaxie werden sie nicht durch das Gravitationsfeld verzerrt; dafür geben sie der ansonsten sehr glatten Szene eine greifbare Bewegung und zeigen die Richtung des Sogs.

Zwei Stücke entstehen zusammen mit dem Bild

Die Produktionsfassung konzentriert sich auf zwei ruhige Tracks. Beide werden mit Oszillatoren, Filtern, Rauschgeneratoren und Effekten der Web Audio API im Browser erzeugt. Es gibt keine Audiodatei, die lediglich abgespielt wird.

Die beiden Tracks der Musikdemo
TrackTempoCharakter
Stille Materie80 BPMBreite Flächen, gestrichene Melodie, E-Piano-Akkorde, Chor im Drop und ein zurückhaltender Herzschlag
Lichtbogen70 BPMWeiter Raum, E-Piano-Melodie, langer Build-up, aufsteigende Läufe, Chor und eine warme gestrichene Linie im Drop

Die Stücke sind absichtlich langsamer als klassische Clubtracks. Das Bild soll nicht auf jedem Sechzehntel hektisch zucken. Es soll atmen. Der Kick ist eher Herzschlag als Schlagzeug, die langen Harmonien lassen Zeit für Kamerafahrten und die leuchtenden Bänder der Scheibe.

Musik wird nicht analysiert, sondern mitkomponiert

Die Demo hört der Musik nicht nachträglich zu. Der Sequencer kennt Takte, Noten und Abschnitte bereits beim Planen des Tons. Neben den eigentlichen Instrumenten legt er Ereignisse wie kick, note, build, drop oder bar in eine Warteschlange. Die Bildregie holt sie passend zur tatsächlichen Audioausgabe ab.

Warum die Audio-Uhr den Takt vorgibt

Der Sequencer arbeitet nicht im Rhythmus von requestAnimationFrame. Ein Timer läuft alle 25 Millisekunden und plant Sechzehntel bis zu 120 Millisekunden im Voraus in die präzise Zeitachse des AudioContext. Derselbe Planungsschritt startet Oszillatoren und Filter und schreibt ein visuelles Ereignis mit identischem Zeitstempel in eine Warteschlange.

Audio und Bild auf derselben Zeitachse javascript
const LOOKAHEAD = 0.12;

while (next < audioContext.currentTime + LOOKAHEAD) {
  scheduleStep(globalStep, next);
  next += secondsPerSixteenth;
}

const playTime = audioContext.currentTime
  - (audioContext.outputLatency || 0)
  - (audioContext.baseLatency || 0);

while (queue.length && queue[0].t <= playTime) {
  director.onEvent(queue.shift());
}

Die Bildseite zieht ein Ereignis erst dann aus der Queue, wenn dessen Klang voraussichtlich am Lautsprecher angekommen ist. outputLatency und baseLatency gleichen dabei den Weg durch Browser und Audiogerät aus. Der Renderloop darf dadurch einmal etwas früher oder später laufen, ohne den Drop vor dem hörbaren Einsatz auszulösen. Die Regie übersetzt das Ereignis anschließend in Zustände wie Energie, Hitze, Wellenradius oder Jet-Stärke; erst diese Zustände werden als Shader-Uniforms geglättet an die Grafikkarte weitergegeben.

Datenfluss vom Track zum Shader text
Track → Sequencer auf der Audio-Uhr ─┬→ Oszillatoren und Filter → Lautsprecher
                                    └→ Ereignis-Queue → Regie → Shader-Uniforms
Musikalische Ereignisse und ihre sichtbare Wirkung
Musikalisches EreignisWirkung im Bild
Kick / HerzschlagEine helle Welle läuft durch die Akkretionsscheibe und schiebt ihre Bänder kurz zusammen.
MelodietonEin Band glüht auf; die Tonhöhe bestimmt seinen Radius.
BassScheibe und Dunst atmen langsam.
Hats und helle AkzenteFunken und Sterne flackern stärker.
Beginn eines HauptteilsEin Stern fällt mehrere Takte lang auf einer Spirale nach innen.
Build-upDie Scheibe heizt auf, Sternenlicht wird zum Sog und die Kamera rückt näher.
DropJets brechen aus den Polen, eine Gravitationswelle kräuselt das Licht und die Kamera geht in die Nahfahrt.

Ein Stern fällt genau im richtigen Moment

Zu Beginn wichtiger Abschnitte erscheint ein heller Stern mit einem dünnen Schweif. Seine Bahn ist als Spirale angelegt, deren Radius immer kleiner wird. Während eines Build-ups berechnet die Regie den Start so, dass der Stern genau am Drop im Schatten verschwindet. In diesem Moment läuft ein schmaler Ring am inneren Rand entlang, als würde die Scheibe auf den Einschlag antworten.

Eine zweite, langsamere Bewegung betrifft die Galaxie im Hintergrund. Sie nähert sich dem Loch, wird zur gebogenen Sichel und schließlich fast zum Einsteinring. Danach wird eine neue Galaxie außerhalb des Bildes vorbereitet. Solche Bewegungen sind nicht sofort als Effekt zu erkennen. Sie sorgen eher dafür, dass die Szene auch in ihren ruhigen Phasen nie völlig stillsteht.

Auftakt und Finale gehören zur Komposition

Der Startbildschirm ist kein bloßes Menü vor der eigentlichen Arbeit. Er ist der erste Zustand der Geschichte. Nach der Trackwahl werden Sterne und Licht eingeblendet, die Scheibe entzündet sich und die Kamera kommt näher. Dieser Auftakt dauert ungefähr zehn Sekunden und gibt dem Auge Zeit, das Schwarze Loch zu entdecken.

Im Outro läuft die Bewegung rückwärts, aber nicht einfach als Fade-out. Die Scheibe wird von außen nach innen eingesogen. Funken, Dunst und Galaxie erlöschen, die Kamera fällt in Richtung Schatten und das Bild geht ins Schwarz. Danach kann ein neuer Auftakt beginnen. Auch der Stoppknopf löst dieses Finale aus – nur in einer kurzen, vier Sekunden langen Fassung.

Diese Übergänge waren wichtiger als erwartet. Ohne sie wäre das Schwarze Loch eine eindrucksvolle Endlosschleife. Mit ihnen bekommt es einen Anfang, eine Entwicklung und ein Ende.

Leistung ist Teil der Gestaltung

Raymarching ist rechenintensiv, weil jeder sichtbare Bildpunkt seinen eigenen Weg durch die Szene verfolgt. Auf dem Desktop verwendet die Demo bis zu 170 Schritte pro Strahl und eine Pixeldichte von 1,5. Mobil beginnt sie mit 110 Schritten und geringerer Auflösung. Wenn die Zielbildrate länger unterschritten wird, sinkt die Pixeldichte stufenweise bis 0,5.

In Ruhe rendert die Anwendung mit 30 Bildern pro Sekunde, während Musik und Übergänge auf 60 Bilder zielen. Diese Begrenzung spart Rechenleistung, wenn das Bild kaum Bewegung enthält. Die Qualität ist damit keine feste Zahl, sondern reagiert auf Gerät und Situation.

Konkretes Renderbudget nach Geräteprofil
BudgetDesktopMobilWirkung
Schritte pro Lichtstrahl170110Obergrenze für die Integration des Strahlwegs
Start-Pixeldichtemaximal 1,5maximal 1,0 × 0,75Begrenzt die tatsächlich berechneten Bildpunkte
Funken700260Jeder Funke wird für sein Nachleuchten fünfmal gezeichnet
Aktive Bildrate60 FPS60 FPSMusik, Übergänge und Interaktion
Ruhebildrate30 FPS30 FPSWeniger GPU-Last ohne sichtbare Aktion

Die adaptive Regelung beobachtet nicht nur einen einzelnen langsamen Frame. Liegt ein aktives Bild über längere Zeit oberhalb von 25 Millisekunden und sammelt damit zwei Sekunden Rückstand, reduziert sie die Pixeldichte auf 80 Prozent des vorherigen Werts. Das kann sich bis zur Untergrenze von 0,5 wiederholen. Die Zahl der Raymarching-Schritte bleibt dabei stabil; zuerst wird also räumliche Auflösung geopfert, nicht die Form der Lichtbahnen.

Eine einzelne Welle in der Scheibe kann mehr erzählen als zehn zusätzliche Effekte, wenn sie musikalisch an der richtigen Stelle erscheint.

Was ich aus der Ereignishorizont-Demo mitnehme

Bei der Partikelmagier-Demo war die Figur der Mittelpunkt. Hier musste die Dramaturgie aus viel weniger Elementen entstehen. Gerade deshalb wurden Licht, Timing und Übergänge wichtiger. Eine einzelne Welle in der Scheibe kann mehr erzählen als zehn zusätzliche Effekte, wenn sie musikalisch an der richtigen Stelle erscheint.

Das Experiment hat mir außerdem gezeigt, dass technische Plausibilität und künstlerische Freiheit gut zusammenpassen. Die Lichtablenkung folgt einer nachvollziehbaren Idee, ist aber auf ein Echtzeitbild im Browser zugeschnitten. Musik und Physik sind keine getrennten Demonstrationen. Beide arbeiten an derselben Stimmung: langsam, schwer und unausweichlich.

Teil 3: Sandtisch – Formen aus KlangWeiterlesen in der Operus Demos-Serie. OPERUS DEMOS