Live ausprobieren Über dieses Projekt
Die sechs Panels sind echte WebGL-Geometrie innerhalb der Scene — sie besitzen Tiefe und Krümmung, verdecken die Figur und werden von ihr verdeckt, und ihre Tiefenreihenfolge bleibt aus jedem Blickwinkel korrekt. Es sind keine DOM-Karten, die über einem Canvas schweben.
Die gesamte Interaktion folgt einer klaren Aufgabenteilung: 3D dient dem Entdecken, 2D der Steuerung. Die Panels übernehmen Browsing und Auswahl, driften um die Figur und folgen den Gesten; die eigentliche Wiedergabesteuerung liegt in der stabilen Screen-Space-Oberfläche am unteren Rand. Die Songauswahl ist kein Zustandswechsel, sondern eine kontinuierliche Übergabe — das Panel selbst fliegt nach unten und wird zum Player; wird ein anderer Track gewählt, fliegt das alte in seinen ursprünglichen 3D-Slot zurück.
Highlights
- Beim Ziehen im leeren Raum kreisen die Musikkarten um die Figur und gleiten mit Trägheit aus; beim Ziehen an der Figur dreht sich nur sie, während Kamera und Panels unverändert bleiben. Beide driften langsam in entgegengesetzte Richtungen — erst diese Gegenbewegung lässt das Cluster wie einen umlaufenden Körper statt wie eine Kulisse wirken.
- Ein Klick löst ein Panel aus dem 3D-Raum: Es schwingt an der Figur vorbei und entfaltet sich unten zu einem horizontalen Player. Wird ein anderes gewählt, sind zwei Panels gleichzeitig in der Luft — das alte faltet sich in exakt seinen ursprünglichen Slot zurück, während das neue nach vorn kommt.
- Das Mausrad fährt die Kamera zwischen 4.6 und 16 World Units vor und zurück: Beim Heranfahren ragen die vorderen Panels über den Bildrahmen hinaus; beim Zurückfahren verdichtet sich der gesamte Raum zu einer von oben gesehenen Musikkonstellation.
- Der Vier-Ecken-Rahmen des Custom Cursors rastet auf dem tatsächlich projizierten Quad jedes Panels ein — die Klammern sitzen auf den echten perspektivischen Ecken und drehen sich mit der Neigung des Panels.
Technische Analyse
3D-Assets · Der unveränderte Tripo-Export
Artist.glb wird exakt so ausgeliefert, wie es aus Tripo exportiert wurde: 59 MB, 1.02M Vertices, eine 8192²-Basisfarbkarte — keine Polygonreduktion, keine Größenänderung, die vollständige erstellte Detailtiefe. Die Kosten sind einkalkuliert (~350 MB VRAM mit mipmap, eine Million pro Frame neu gezeichnete Vertices), und zwei Entscheidungen halten sie beherrschbar: Das schwere Mesh wird vom Raycasting ausgenommen — eine Million Dreiecke pro Pointer-Bewegung würden den Main Thread blockieren — und durch eine unsichtbare Kapsel ersetzt, deren Größe aus den Bounds des Modells abgeleitet ist; da der Export außerdem keine Animationsclips enthält, erhält die Figur statt eines erfundenen Skeletts eine Idle-Animation auf Gruppenebene (langsames Wiegen plus einen Millimeter Atembewegung).
Eine meshopt-Pipeline in scripts/ reduziert dieselbe Datei auf 2.9 MB; das Modell wird beim Laden vermessen und normalisiert, sodass sich Builds ohne Codeänderung austauschen lassen.
Materialien · Das Volume-Material in Tripo-Exporten gezielt vereinfachen
Tripo-Exporte versehen das Mesh mit KHR_materials_volume; in three.js wird daraus ein MeshPhysicalMaterial mit einem transmission/thickness-Pfad, den diese Scene weder braucht noch bezahlen kann. Beim Laden wird jedes Material zu MeshStandardMaterial heruntergestuft, während der vollständige Satz an PBR-Maps erhalten bleibt — gleiche Optik, ohne die zusätzlichen Kosten.
Custom ShaderMaterials binden colorspace_fragment explizit ein: Ohne diesen Schritt schreiben sie lineare Werte direkt in einen sRGB-Framebuffer und werden nahezu schwarz gerendert.
Musik-Panels · Echte Geometrie auf einer Kurve
Jedes Panel besteht aus vier Geometriearten — einer Vorderseite, einem für echte Tiefe extrudierten Randstreifen, einer transluzenten Rückplatte und unsichtbaren Hit-Quads. Alle teilen sich einen gecachten Buffer-Satz; nur die Gruppentransformation unterscheidet sich je Karte. Alles wird flach erstellt und auf einen großen vertikalen Zylinder gewickelt: Fortschrittsrinne und Uhr sind direkt in dieselbe Kurve eingebacken statt ihr untergeordnet, und die Fortschrittsfüllung ist ein in ein MeshBasicMaterial injizierter UV-Cutoff — die Skalierung eines Meshes würde sein entferntes Ende von der Kurve abheben.
Die Panel-Grafik verteilt sich nach Aktualisierungsfrequenz auf drei Canvas: Die 1320×680-Vorderseite wird einmal gezeichnet, der Zeitstreifen nur beim Wechsel der angezeigten Sekunde, das Icon nur beim Umschalten der Wiedergabe — im Render Loop geschieht nichts Aufwendiges. Alle sechs transparenten Panels verzichten auf Depth Writes und erhalten in jedem Frame eine nach Kameradistanz gestaffelte renderOrder, sodass die Verdeckung aus jedem Winkel korrekt bleibt.
3D-zu-2D-Übergabe · Eine Karte wird zum Player
Ein WebGL-Mesh kann nicht zu einem DOM-Knoten werden. Deshalb entsteht Kontinuität aus drei Bausteinen: Ein Projektor hält in jedem Frame die Screen-Space-Box jeder Karte aktuell — auch bei ausgeblendeten Karten, denn der Rückflug braucht ein Ziel; im ersten Frame zeigt das DOM-Panel exakt jene Canvas-Bitmap, die bereits als WebGL-Textur der Karte gerendert wurde, nicht eine HTML-Nachbildung, die nie vollkommen deckungsgleich wäre; und die Karte wird im selben Frame ausgeblendet — zwei Dinge am selben Ort, eines davon unsichtbar.
Die Verbreiterung setzt erst ein, wenn der Flug zu ~35% abgeschlossen ist — eine 2:1-Karte mitten im Flug auf eine 11:1-Leiste zu strecken, würde das Motiv verwaschen —, und die Flugbahn folgt einer seitlich gewölbten quadratischen Bézierkurve. So schwingt eine Karte, die von links oben andockt, um die Figur herum. Das Ziel wird in jedem Frame neu erfasst: Die Konstellation driftet weiter, und ein beim Start erfasstes rect würde das Panel neben seiner Karte landen lassen.


