{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "scroll-3d-kamerafahrt",
 "name": "Scroll-gesteuerte 3D-Szene / 3D-Modell (Kamerafahrt)",
 "name_en": "Scroll-driven 3D product / camera path / Scroll-driven WebGL scene / camera path",
 "kurz": "Ein Architekturmodell am Weinberg: Der Scroll fährt die Kamera auf einer CatmullRom-Kurve durch vier Kapitel, geglättet mit damp, synchron zu HTML-Texten und Beschriftungen am Modell.",
 "kategorie": "3D & WebGL",
 "kategorie_slug": "3d-webgl",
 "kategorie_nr": 11,
 "bau_chat": "C5",
 "prioritaet": "A",
 "trendstatus": "etabliert",
 "belegstatus": "teilbelegt",
 "website_belege": 1,
 "stimmung": [
  "präzise",
  "luxuriös",
  "filmisch",
  "laut",
  "experimentell"
 ],
 "stimmung_roh": [
  "filmisch",
  "hochwertig",
  "technisch",
  "immersiv",
  "futuristisch",
  "laut"
 ],
 "technik": [
  "three",
  "r3f",
  "gsap",
  "scrolltrigger",
  "lenis",
  "webgl-shader"
 ],
 "technik_gruppen": [
  "gsap",
  "lenis",
  "webgl"
 ],
 "leistungskosten": "hoch",
 "steckbrief": {
  "beschreibung": "Eine fixierte Canvas liegt hinter normal scrollendem HTML. Der Scrollfortschritt wird zu einem einzigen Wert. Dieser Wert steuert die Kamera entlang einer Kurve (CatmullRomCurve3) oder das Modell selbst: Drehung, Explosionsansicht, Material, Licht. Jedes Kapitel hat einen Keyframe. Der Wert wird geglättet (damp oder lerp), damit Scroll-Rucke nicht durchschlagen. HTML-Texte und Beschriftungen laufen synchron und zeigen auf Teile des Modells.",
  "warum_es_wirkt": "Der Nutzer steuert die Erzählung selbst. Das Produkt wird von allen Seiten erfahrbar, ohne Video. Die Seite wird zur Markenwelt. Award-Seiten der Developer-Kategorie leben davon.",
  "wann_einsetzen": "Produktlaunches, Hardware, Fahrzeuge, Architekturmodelle, Kampagnen und Studio-Portfolios. Auch für konzeptuelle Produkte, die ein Alltagsobjekt groß inszenieren.",
  "wann_nicht": "Wenn Inhalte schnell gefunden werden müssen, etwa auf Informationsseiten und in Shops. Ohne optimiertes Modell (Draco oder Meshopt, KTX2), ohne 3D-Kompetenz und bei schwachen Zielgeräten. Nie ohne HTML-Inhalt als Grundlage.",
  "varianten": [
   "Kamerafahrt durch die Szene entlang einer CatmullRom-Kurve.",
   "Explosionsansicht: Das Objekt zerlegt sich Kapitel für Kapitel.",
   "Drehung am Platz mit Beschriftungen zu einzelnen Merkmalen.",
   "Selektives WebGL: 3D nur an Schlüsselmomenten (Lusion, Atlas Motion).",
   "Flug über ein 3D-Terrain (Ridgeline).",
   "WebGL-Flächen, die DOM-Positionen folgen: Bilder im Canvas laufen mit dem Layout.",
   "Scroll steuert Shader-Uniforms, etwa Dissolve oder Noise.",
   "Die ganze Seite als durchgehende Szene, Kapitel für Kapitel mit HTML synchronisiert."
  ],
  "umsetzung": "Den Fortschritt zentral halten: pro Kapitel ein Wert, die Szene liest nur diesen Wert und nie das DOM. Mit ScrollTrigger: state.target = progress. Im Render-Loop: state.current = damp(state.current, state.target, 6, dt), dann camera.position.copy(curve.getPoint(state.current)). Die Canvas ist position: fixed mit pointer-events: none. Modelle mit gltf-transform komprimieren, Texturen als KTX2, schwere Kapitel erst bei Bedarf laden. Shader beim Laden vorkompilieren (renderer.compile). Pixelratio auf 1,5 bis 2 begrenzen. Rendern pausieren, wenn sich nichts bewegt oder die Canvas nicht sichtbar ist. Fallstricke: Ladegewicht, Speichergrenzen auf iOS, Lesbarkeit von Text über bewegtem Bild und die Adressleiste auf iOS, die die Viewporthöhe ändert (100lvh oder svh verwenden).",
  "mobil": "Leichteres Modell (LOD), Pixelratio höchstens 1,5 bis 2, kleinere Shadow-Map. Bildausschnitt und Textlage an das Hochformat anpassen. Bei schwachen Geräten eine Bildsequenz oder ein vorgerendertes Video statt Echtzeit.",
  "reduzierte_bewegung": "Keine Fahrt: Die Kamera springt pro Kapitel zur Schlüsselpose. Alternativ ein statisches Rendering je Kapitel.",
  "barrierefreiheit": "Alle Informationen stehen im HTML, nicht nur im Canvas. Die Canvas ist aria-hidden. Den Scroll nicht kapern, Tastatur-Scroll muss genauso funktionieren. Kapitel-Anker in der Navigation bieten einen Tastaturpfad."
 },
 "messwerte": {
  "easing": "damp mit lambda 4–8 (maath/easing)",
  "dauer_ms": "",
  "stagger_ms": "",
  "distanz": "Abschnitte 100–300vh pro Kamera-Keyframe",
  "sonstiges": "pixelRatio ≤ 2",
  "herkunft": "typisch",
  "quelle": "",
  "aus_eintrag": [
   "scroll-3d-modell",
   "webgl-scroll-szene"
  ]
 },
 "kurve": null,
 "gesehen_bei": [
  {
   "seite": "Oryzo AI (Lusion)",
   "url": "https://lusion.co/projects/oryzo_ai",
   "auszeichnung": "Awwwards und FWA Site of the Month (Monat nicht angegeben)",
   "beobachtung": "Satirischer Produktlaunch eines Korkuntersetzers als KI-Produkt, 3D/WebGL/Animation als Leistungen; inszeniert ein Alltagsobjekt mit Produktfilm-Ästhetik (Details der Scroll-Mechanik nicht dokumentiert).",
   "art": "website",
   "browser_gemessen": true
  },
  {
   "seite": "Atlas Motion (Lusion)",
   "url": "https://lusion.co/projects/atlas_motion",
   "auszeichnung": "",
   "beobachtung": "Ausdrücklich selektives WebGL: 3D nur an bestimmten Momenten, präzise Bewegung, zurückhaltender 3D-Einsatz für seriöse Industrie.",
   "art": "website",
   "browser_gemessen": true
  },
  {
   "seite": "Codrops – Building Ridgeline",
   "url": "https://tympanus.net/codrops/2026/07/22/building-ridgeline-engineering-a-real-time-3d-experience-in-webflow/",
   "auszeichnung": "",
   "beobachtung": "Laut Feed: Echtzeit-3D in Webflow mit Terrain-Rendering, Animation und Performance-Arbeit.",
   "art": "artikel"
  },
  {
   "seite": "Igloo Inc.",
   "url": "https://igloo.inc",
   "auszeichnung": "Awwwards SOTD 23.07.2024 + Developer Award (Animations/Transitions 9,60)",
   "beobachtung": "Aus Erinnerung (nicht verifiziert): durchgehende 3D-Eis-Szene, die per Scroll durchfahren wird.",
   "art": "website-ungeprueft",
   "browser_gemessen": true
  },
  {
   "seite": "Lusion",
   "url": "https://lusion.co",
   "auszeichnung": "Awwwards SOTD 02.10.2023 (v3), Developer Award 8,41",
   "beobachtung": "‚scroll to explore‘, ‚CONTINUE TO SCROLL‘ und ‚Step into a new world‘ im Markup – scroll-geführte 3D-Erzählung; Szenendetails im Browser prüfen.",
   "art": "website",
   "browser_gemessen": true
  }
 ],
 "tutorials": [
  {
   "titel": "Building Ridgeline: Engineering a Real-Time 3D Experience in Webflow",
   "url": "https://tympanus.net/codrops/2026/07/22/building-ridgeline-engineering-a-real-time-3d-experience-in-webflow/"
  },
  {
   "titel": "Olivier Larose – 3D Wave on Scroll",
   "url": "https://blog.olivierlarose.com/tutorials/3d-wave-on-scroll"
  }
 ],
 "kombinierbar_mit": [
  "glas-transmission-3d",
  "seitenwechsel-kamerafahrt",
  "nachbearbeitung-filmlook",
  "smooth-scroll-lenis",
  "pinned-scrub-scrollytelling",
  "scroll-fortschritt"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/3d-webgl/scroll-3d-kamerafahrt/",
  "meta": "https://cecodesign.de/lab/fundus/3d-webgl/scroll-3d-kamerafahrt/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/3d-webgl/scroll-3d-kamerafahrt/demo"
 },
 "herkunft": {
  "quelldateien": [
   "material3d.json",
   "scroll.json"
  ],
  "zusammengelegt_aus": [
   "scroll-3d-modell",
   "webgl-scroll-szene"
  ],
  "querverweis_kategorien": [
   "Scroll & Section-Animationen"
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Ein Architekturmodell am Weinberg: Der Scroll fährt die Kamera auf einer CatmullRom-Kurve durch vier Kapitel, geglättet mit damp, synchron zu HTML-Texten und Beschriftungen am Modell.",
  "demo": true,
  "abhaengigkeiten": [
   "three@0.186.0"
  ],
  "werte": {
   "glaettung": "damp(aktuell, ziel, λ 6, dt) = lerp(a, b, 1 − e^(−6·dt)), wie maath/easing; dt begrenzt auf 0–0,5 s",
   "fortschritt": "ein Wert t von 0 bis 3; Kapitel i liegt genau bei t = i (Kapitelmitte in Bildschirmmitte), dazwischen smoothstep f²(3 − 2f) zum Verweilen am Keyframe",
   "kapitel": "150vh je Kamera-Keyframe (Telefon 150svh), Hero 130vh",
   "kamerapfad": "CatmullRomCurve3 centripetal, 7 Punkte für Position und 7 für Blickziel; Kapitel i auf Punkt 2·i, dazwischen Stützpunkte; getPoint(t / 3)",
   "fov": "30 / 42 / 34 / 38 je Kapitel (Kamerafahrt), Telefon ×1,32 und 12 % weiter weg",
   "explosion": "Anteil 0 / 0,55 / 1 / 0 je Kapitel; Hub Sockel 2 m, Riegel 6 m, Dach 10 m",
   "drehung": "Modell 0° / −43° / −120° / −195° je Kapitel, Kamera fest bei (40, 25, 46), fov 32",
   "variantenwechsel": "Überblendung der Kamerakurven mit damp λ 4",
   "licht": "Tageslauf je Kapitel: Sonnenhöhe 52° / 40° / 66° / 13°, Farbe #fff2e2 → #ffb57a, Stärke 2,6 / 2,4 / 2,8 / 2,3; Fensterleuchten 0,06 → 0,28",
   "bildausschnitt": "setViewOffset: Desktop Modell um 14 % (unter 1300 px 19 %) nach rechts, Telefon um 13 % nach oben",
   "beschriftung": "an 3D-Punkte gehängt, je Frame projiziert; sichtbar bei |t − i| < 0,32; Einblenden opacity 600 ms cubic-bezier(0.16, 1, 0.3, 1)",
   "einblenden": "Canvas opacity 1400 ms cubic-bezier(0.16, 1, 0.3, 1) nach renderer.compile",
   "ui": "Umschalter 150 ms linear",
   "pixelratio": "max. 2, Touch max. 1,5",
   "schatten": "DirectionalLight, PCF, Shadow-Map 2048 (Touch und Vorschau 1024), radius 3",
   "geometrie": "nur Boxen, Ikosaeder und Zylinder; 1 InstancedMesh für die Rebzeilen; Holz- und Betonstruktur als Canvas-Textur, kein Modell-Download",
   "rendern": "nur solange sich t oder die Variantenmischung ändert (Schwelle 0,0004), sonst Stillstand",
   "vorfuehrung": "simulierter Scroll hin und zurück, 22 s je Runde, Kosinusverlauf",
   "kopf": "Kopf deckend in Grundfarbe bis unter Logo und Navigation, darunter 48 px Verlauf (Telefon 72 px); Kapiteltexte per mask-image im Viewport verankert, zeilengenau 80 px Ausblendung, ganz weg 8 px unter dem Kopf (Telefon unter der Werte-Zeile)"
  },
  "ausloeser": "scroll",
  "touch": "Normaler Scroll mit dem Finger, kein Kapern. Texte stehen unten über einem Verlauf, das Modell sitzt im oberen Bilddrittel. Weiterer Bildausschnitt, kurze Beschriftungen, Pixelratio 1,5, Shadow-Map 1024. Höhe 100lvh, damit die Adressleiste die Szene nicht neu skaliert.",
  "reduziert": "Keine Kamerafahrt: Die Kamera springt zur Schlüsselpose des Kapitels, das gerade in der Mitte steht. Kein Nachlauf, kein Überblenden der Varianten, Beschriftungen nur kurz eingeblendet. Die Vorführung springt alle 2,6 s ein Kapitel weiter.",
  "korrekturen": {
   "beschreibung": "Eine fixierte Canvas liegt hinter normal scrollendem HTML. Der Scrollfortschritt wird zu einem einzigen Wert. Dieser Wert steuert die Kamera entlang einer Kurve (CatmullRomCurve3) oder das Modell selbst: Drehung, Explosionsansicht, Material, Licht. Jedes Kapitel hat einen Keyframe. Der Wert wird geglättet (damp oder lerp), damit Scroll-Rucke nicht durchschlagen. HTML-Texte und Beschriftungen laufen synchron und zeigen auf Teile des Modells.",
   "warum_es_wirkt": "Der Nutzer steuert die Erzählung selbst. Das Produkt wird von allen Seiten erfahrbar, ohne Video. Die Seite wird zur Markenwelt. Award-Seiten der Developer-Kategorie leben davon.",
   "wann_einsetzen": "Produktlaunches, Hardware, Fahrzeuge, Architekturmodelle, Kampagnen und Studio-Portfolios. Auch für konzeptuelle Produkte, die ein Alltagsobjekt groß inszenieren.",
   "wann_nicht": "Wenn Inhalte schnell gefunden werden müssen, etwa auf Informationsseiten und in Shops. Ohne optimiertes Modell (Draco oder Meshopt, KTX2), ohne 3D-Kompetenz und bei schwachen Zielgeräten. Nie ohne HTML-Inhalt als Grundlage.",
   "varianten": [
    "Kamerafahrt durch die Szene entlang einer CatmullRom-Kurve.",
    "Explosionsansicht: Das Objekt zerlegt sich Kapitel für Kapitel.",
    "Drehung am Platz mit Beschriftungen zu einzelnen Merkmalen.",
    "Selektives WebGL: 3D nur an Schlüsselmomenten (Lusion, Atlas Motion).",
    "Flug über ein 3D-Terrain (Ridgeline).",
    "WebGL-Flächen, die DOM-Positionen folgen: Bilder im Canvas laufen mit dem Layout.",
    "Scroll steuert Shader-Uniforms, etwa Dissolve oder Noise.",
    "Die ganze Seite als durchgehende Szene, Kapitel für Kapitel mit HTML synchronisiert."
   ],
   "umsetzung": "Den Fortschritt zentral halten: pro Kapitel ein Wert, die Szene liest nur diesen Wert und nie das DOM. Mit ScrollTrigger: state.target = progress. Im Render-Loop: state.current = damp(state.current, state.target, 6, dt), dann camera.position.copy(curve.getPoint(state.current)). Die Canvas ist position: fixed mit pointer-events: none. Modelle mit gltf-transform komprimieren, Texturen als KTX2, schwere Kapitel erst bei Bedarf laden. Shader beim Laden vorkompilieren (renderer.compile). Pixelratio auf 1,5 bis 2 begrenzen. Rendern pausieren, wenn sich nichts bewegt oder die Canvas nicht sichtbar ist. Fallstricke: Ladegewicht, Speichergrenzen auf iOS, Lesbarkeit von Text über bewegtem Bild und die Adressleiste auf iOS, die die Viewporthöhe ändert (100lvh oder svh verwenden).",
   "mobil": "Leichteres Modell (LOD), Pixelratio höchstens 1,5 bis 2, kleinere Shadow-Map. Bildausschnitt und Textlage an das Hochformat anpassen. Bei schwachen Geräten eine Bildsequenz oder ein vorgerendertes Video statt Echtzeit.",
   "reduzierte_bewegung": "Keine Fahrt: Die Kamera springt pro Kapitel zur Schlüsselpose. Alternativ ein statisches Rendering je Kapitel.",
   "barrierefreiheit": "Alle Informationen stehen im HTML, nicht nur im Canvas. Die Canvas ist aria-hidden. Den Scroll nicht kapern, Tastatur-Scroll muss genauso funktionieren. Kapitel-Anker in der Navigation bieten einen Tastaturpfad."
  },
  "geprueft": "01.11.2026",
  "notiz": "Erfundenes Büro Brandt & Okafor mit einem Weinberghaus in Radebeul als Architekturmodell: Hang aus Kartonschichten, Rebzeilen, Betonsockel und auskragender Holzriegel mit Lichthof, alles aus Grundkörpern und Canvas-Texturen gebaut (kein Modell-Download). Vier HTML-Kapitel steuern einen Fortschritt t, damp λ 6 glättet ihn. Umschalter für drei Varianten: Kamerafahrt (CatmullRom, 7 Punkte), Explosion (Sockel, Riegel, Dach heben ab) und Drehung am Platz. Dazu ein Tageslauf im Licht und Beschriftungen, die an 3D-Punkten hängen. Ohne WebGL steht eine SVG-Skizze. Die Vorführung verschiebt den Inhalt statt echt zu scrollen. In der Demo ohne GSAP und Lenis gebaut, in Produktion passen ScrollTrigger und Lenis direkt dazu. 01.11.2026: Nach dem Scrollen lief der Text von Kapitel 1 schwach hinter Logo und Navigation durch, weil der Kopfverlauf nur 88 % deckte. Jetzt deckt der Kopf voll, und jede Textzeile der Karten blendet über eine im Viewport verankerte Maske aus, bevor sie den Kopf erreicht; das gilt auch in der Vorführung mit verschobenem Inhalt. Zugang 02.11.2026: Labels im hellen Schlussteil Alpha .58 auf .66 (5,2:1), Knopfrahmen im Kontrastmodus. „Bewegung ohne Pause“ ist ein Fehlalarm: unter Swiftshader blendet die Szene erst nach 6 bis 10 s ein, danach steht das Bild (Schleife rendert nur bei Scroll oder Vorführung)."
 }
}
