Chrono in Unreal, Teil 8: Das Licht der Nacht
Der letzte Drittel der Demo spielt in der Dämmerung und in der Nacht. Die erste Fassung hat die Nacht so gemacht, wie man es aus Spielen kennt: ein Nachfilter, der das Bild abdunkelt und blau färbt. Der Entwickler hat das verworfen, “du musst die Lichtquelle einstellen”, und der Satz ist das Programm dieses Teils. Die Nacht entsteht hier aus der Belichtung und aus Lichtquellen, nicht aus einer Nachbearbeitung. Die Reihe: Teil 1 Überblick, Teil 5 die Effekte des Tages, Teil 6 Parasail, Teil 7 Drohne, Teil 9 Sequenz.
Die Demo, um die es in der Serie geht. Der Abend ab Minute 6:03. Auf YouTube in 1080p ist die Konsole lesbar.
Die Belichtung als Kamera
Die Engine belichtet automatisch, wie ein Auge oder eine Kamera in Automatik: sie passt sich der mittleren Helligkeit an. Für eine Nacht ist das das Gegenteil dessen, was man will, denn die Automatik holt aus jeder Dunkelheit wieder ein mittelhelles Bild heraus, und aus dem Vollmond wird ein blasser Tag. Die erste Version hat deshalb mit einer unteren Belichtungsgrenze gearbeitet, die mit der Dämmerung sank. Das Ergebnis war entweder Tag oder schwarz, je nach Grenze, und nie beides in einem Übergang.
Die Lösung ist eine Kamera mit fester Einstellung. Vom Beginn des Sonnenuntergangs an werden untere und obere Grenze der Belichtung auf denselben Wert gesetzt, den Tageswert. Er ist aus der Sonnenstärke berechnet: die Leuchtdichte einer Szene ist etwa Beleuchtungsstärke mal Albedo durch π, und daraus folgt der Belichtungswert EV100 = log₂(L · 100 / 12.5), mit einem kleinen Versatz für die Abstimmung. Die Grenzen laufen über acht Sekunden auf diesen Wert, damit nichts springt. Ab dann ist die Belichtung eine Konstante, und die Helligkeit jedes Pixels ist nur noch das, was die Lichtquellen liefern. Die Sonne sinkt und wird schwächer, das Bild wird dunkler, und was dann leuchtet, sind Mond, Bootslichter, Suchscheinwerfer und die Blink-LED der Drohne.
Das hat eine Konsequenz für die Lichtstärken: sie müssen zueinander passen, nicht zu einer Automatik. Die Sonne geht in 45 Sekunden von 26 Grad Höhe bis auf den Horizont und dabei auf 35 Prozent ihrer Stärke, wärmer im Ton und mit einer Scheibe, die von 0.5 auf 2.5 Grad wächst. In weiteren 15 Sekunden fällt sie auf 0.3 Prozent, mit dem Mondaufgang auf 0.05 Prozent. Unter den Horizont geht sie dabei nicht: die Lichtrichtung bleibt bei 6 bis 7 Grad über dem Horizont stehen, die Nacht macht allein die Stärke, und das HUD liest in der Nacht “sun +7 deg 0.00 lux”. Der Mond bekommt 15 Prozent der Tagessonne. Physikalisch ist der Vollmond rund 400000 mal schwächer als die Sonne, und mit der festen Belichtung wäre die Nacht damit schwarz. 15 Prozent ist der Wert, bei dem man bei fester Kamera Strand, Boot und Schirm noch sieht und die Szene trotzdem als Nacht liest. Das ist eine Entscheidung für das Bild, und sie ist hier als solche benannt.
Der Mond
Der Mond ist ein zweites gerichtetes Licht, das als Atmosphärenlicht eingetragen ist, damit der Himmel um ihn herum dunkelblau wird und nicht schwarz. Zwei Details entscheiden, ob das funktioniert. Erstens muss die Sonne das Licht mit Vorrang für Wasser, Transparenz und Nebel bleiben, sonst rechnet die Engine diese Effekte mit dem Mond und warnt; das ist eine Priorität am Licht. Zweitens erzeugt die Atmosphäre für jedes ihrer Lichter eine eigene Scheibe am Himmel. Die Quellgrösse des Mondlichts ist so klein gesetzt, dass diese Scheibe als Punkt in der sichtbaren Mondkugel verschwindet.
Die sichtbare Mondkugel ist ein unbeleuchtetes Objekt mit einer Textur, 200 Kilometer entfernt entlang der Lichtrichtung, mit 2.2 Grad Durchmesser skaliert. Der Abstand ist nicht kosmetisch. Bei 40 Kilometern wanderte die Kugel gegen die Atmosphärenscheibe, sobald sich die Kamera bewegte, Parallaxe, und sie stand vor den volumetrischen Wolken. Bei 200 Kilometern ist die Parallaxe unter einem Pixel und die Kugel hinter den Wolken. Die Textur ist prozedural erzeugt, weil der Mond mit dem Foto aus der Bibliothek in dieser Grösse nur ein heller Fleck war: die grossen Maria ungefähr an ihren Orten, ein helles Hochland, einige tausend Krater mit beleuchtetem Rand, Tycho und Kopernikus mit Strahlen. “Merkt niemand”, war die Auflage, und das Ziel war ein Mond, der als Mond lesbar ist, nicht eine Karte.
Der Mondaufgang ist auf die Handlung getaktet: 78 Sekunden nach Beginn der Dämmerung, kurz bevor das Boot auf den Strand fährt, kommt er über 25 Sekunden hinter der Düne hoch, von 4 Grad unter dem Horizont auf 24 Grad darüber, und sein Licht kommt mit ihm. Der Strandlauf und die Landung des Schirms liegen damit im Mondlicht, “bevor er ans Land knallt, muss wieder Licht da sein”.

Sterne und Sternschnuppen
900 Sterne als ein einziges Instanced Static Mesh, kleine Scheiben in 200 Kilometern Entfernung, wieder hinter den Wolken, mit Durchmessern zwischen 0.2 und 0.5 Grad. Das Funkeln ist im Material: der Zufallswert pro Instanz, den die Engine bereitstellt, gibt jedem Stern eine eigene Phase und Rate, mit der seine Helligkeit über der Zeit moduliert wird. So funkelt jeder Stern für sich, ohne dass irgendjemand pro Bild 900 Objekte anfasst. Die Hauptsterne des Wassermanns sind aus Rektaszension und Deklination gelegt, die übrigen zufällig und nicht zu nah an ihnen. Die Sternschnuppe ist ein additiver Zylinder, der ab und zu ein Stück Himmel quert, mit Kopf und einem Schweif von einem Viertel der Bahn.
Die Lichter des Bootes
Die Bootslichter folgen den Kollisionsverhütungsregeln, denn der Entwickler kannte sie und hat das Bild danach beurteilt: rot nach Backbord, grün nach Steuerbord, jedes über einen Sektor von 112.5 Grad von recht voraus bis 22.5 Grad achterlicher als querab, dazu ein weisses Topplicht über 225 Grad und ein Hecklicht über 135 Grad. Zwei Fassungen mit Spotlights stimmten nicht. Die erste neigte den Kegel 25 Grad nach unten, damit er aufs Wasser leuchtet; ein Kreiskegel mit Halbwinkel a um eine um e geneigte Achse spannt in der Horizontalen aber asin(sin a / cos e), und der Sektor reichte 10 Grad zu weit nach achtern. Die zweite sass an der Bugspitze, und weil ein Spot auf seiner Achse am hellsten ist, ging das meiste Licht in den vorderen Quadranten. Ein Kegel ist die falsche Form für einen Sektor, der in jeder Höhe gleich breit sein muss. Die Laternen sind jetzt Punktlichter mit einer Lichtfunktion, einem Material, das pro beleuchtetem Punkt einen Faktor liefert: die Richtung von der Lampe zum Punkt wird auf die Horizontale projiziert und mit der Sektormitte skalar multipliziert, und der Faktor ist 1, wenn das Produkt über dem Kosinus des halben Sektors liegt, sonst 0. Lampenposition und Sektormitte bekommt das Material jedes Bild aus der Lage des Bootes. Es gibt ein Winkelsystem für alle Lampen: 0 Grad ist recht voraus, positiv im Uhrzeigersinn von oben gesehen, grün deckt 0 bis 112.5 Grad, rot 247.5 bis 360, das Topplicht 247.5 über 0 bis 112.5, das Hecklicht 112.5 bis 247.5. Vier Laternen: rot und grün an den Enden des oberen Turmholms, auf der vollen Bootsbreite bei ±1.15 Metern und 1.88 Metern Höhe, damit ihre Vorauskanten den Bordwänden entlang laufen, und eine Mittellaterne auf der Längsachse, links rot, rechts grün, mit einer schwarzen Trennwand, damit sich die Sektoren recht voraus in der Mitte treffen. Die Lampengehäuse sind hinten und innen geschlossen.
Das Wasser hat eine Grenze der Engine sichtbar gemacht, die es lohnt zu kennen. Auf Sand und Rumpf stimmen die Sektoren, auf dem Wasser leuchtet jede Laterne rundum. Das Wassermaterial ist transluzent, und der klassische Durchgang für Lichtfunktionen rekonstruiert den beleuchteten Punkt aus dem Tiefenpuffer, in dem transluzente Pixel nicht liegen. Für Transluzenz, Nebel und Lumen gibt es Lichtfunktionen nur über den Lichtfunktions-Atlas, und der nimmt nur Materialien ohne Weltposition an, weil er die Funktion in eine zweidimensionale Kachel über der Lichtrichtung backt. Dazu kommt die Farbe des Wassers, ein Blaugrün, das grünes Licht rund achtmal besser zurückwirft als rotes: man sieht grün auch von achtern und rot fast gar nicht. Der Weg dahin, die Sektormaske aus den Lichtkoordinaten statt aus der Weltposition zu rechnen und die Sektormitte in die Drehung der Lampe zu legen, ist bekannt und für dieses Video nicht mehr gegangen worden. Das Wasser vor dem Boot bekommt sein Licht von zwei weissen Scheinwerfern am Bug, waagrecht nach vorn gerichtet wie bei einem Auto, mit 18 und 30 Grad Kegel; die Laternen sind mit 30 Candela und 12 Metern Reichweite Laternen und keine Flutlichter. Ein rotes Blinklicht hat das Boot nicht, das gehört der Drohne.
Der Suchscheinwerfer ist das einzige Licht mit Schatten, und das eine, das den Abend trägt. Sobald es dunkel ist, wandert er 22 Sekunden über den Strand, hält dann 14 Sekunden auf den Schirm, und so weiter, bis er beim Strandlauf auf dem Schirm bleibt; am Ende hält er auf das Wrack, in dem die Drohne treibt. Der Kegel selbst ist sichtbar, weil ein Spotlight in der Engine nur beleuchtet, was es trifft, und Luft trifft es nicht: ein additiver Kegel aus einem Grundkörper, schwach, mit der Länge bis zum Ziel plus 20 Meter und der Basis so breit wie der äussere Kegel des Lichts dort. Drei geschachtelte Kegel für ein Abklingen zum Ziel hin waren die zweite Version; die erste, ein einzelner schwacher Kegel, war die, die geblieben ist: “der alte Scheinwerfer war besser”.
Die Blink-LED der Drohne ist ein Doppelblitz pro Sekunde, eine kleine leuchtende Kugel und ein Punktlicht, und sie geht mit den Bootslichtern an, bei 45 Prozent des Sonnenuntergangs, weil der Entwickler die Drohne im Bild des Fahrzeugs sonst nicht mehr fand.

Materialien, die im Video nicht rauschen
Zwei Materialänderungen gehören zum Licht, obwohl sie tagsüber gemacht wurden. Im Meer und auf dem Sand war im verkleinerten Video ein Rauschen zu sehen: die 25 cm Wellennormalen des Wassers und die Rippel des Sands sind ab 60 bis 100 Metern feiner als ein Pixel und werden vom Encoder zu Flimmern. Beide Materialien blenden ihre Normalen und ihre Rauheit mit der Pixeltiefe aus, fern ist das Wasser glatt und flach schattiert, der Sand ohne Rippel. Bei Nacht mit dem Suchscheinwerfer auf dem Wasser ist der Unterschied am grössten. Die Leine des Parasails hat ein leicht emissives Material, damit sie im Kegel des Scheinwerfers zu sehen ist; ohne das war sie im Video verschwunden, und der Entwickler hat drei Läufe lang eine dickere Leine verlangt, bis klar war, dass sie kein Licht hatte.
Was es kostet
Der Suchscheinwerfer mit Schatten ist das eine teure Licht. Alle anderen werfen keine Schatten, die Sterne sind ein Zeichenaufruf, die Mondkugel einer. Im gezeigten Lauf steigt die GPU Zeit von rund 12 Millisekunden bei Tag auf 14 bis 16 in der Nacht, die Bildrate bleibt bei 56 bis 57 Bildern pro Sekunde.
Zwei Tage für die ganze Umsetzung, vom Setup bis zur Nacht: das Tempo kam aus der Automation, nicht aus abgekürzten Modellen. Gearbeitet wurde als Paar, mit klarer Rollenteilung. Der Ingenieur brachte die Modellphysik und die Praxiskenntnisse mit, die eine kalibrierte Simulation von einer hübschen Animation trennen, und formulierte daraus die Anforderungen an das System. Beispiele: Der Auftrieb des Schirms ist geschwindigkeitsabhängig, das Boot regelt die Höhe über die Fahrt und nicht über die Kamera, die Leine zum Piloten hängt an der Brust und nicht am Sitz, die Nacht kommt aus Lichtquellen und nicht aus einem Filter, Seitenlichter sind rot backbord und grün steuerbord und decken einen 112.5-Grad-Sektor mit sauberem Schluss achterlich. Ein Banner hinter dem Schirm sah albern aus und flog wieder raus. Solche Vorgaben stammen nicht aus einem Prompt, sondern aus Physik und Praxis auf dem Wasser. Der Agent, Claude™ Code, hat aus diesen Anforderungen den C++-Code, die Materialien und die Blueprints gebaut, kompiliert, gestartet, Screenshots gezogen, die Telemetrie gelesen und Vorschläge gemacht. Am Modell gemessen wurde entschieden, was blieb. Nur einmal musste der Quellcode reviewt werden, um weiterzukommen: bei den Sektorlichtern, deren Lichtfunktion das Wasser nicht erreichte.
Wie diese Szenen zu einer Sequenz von neun Minuten ohne Eingriff zusammenlaufen, mit Ereignissen als Übergängen, steht in Teil 9.
Schlüsselwörter: Unreal Engine Nacht Beleuchtung, Belichtung fixieren Auto Exposure, Mond Directional Light Atmosphäre, prozedurale Mondtextur, Sterne Instanced Static Mesh funkeln, Positionslichter Lichtfunktion Sektor, Light Function Atlas Transluzenz, Suchscheinwerfer sichtbarer Kegel, Material Distanz Rauschen Video, Serious Gaming, Simulation Beratung Schweiz, swissEmbedded
Ein Bild, das aus Lichtquellen entsteht statt aus Filtern? Wir bauen Visualisierungen, deren Helligkeit und Farbe aus der Szene kommen, für Simulatoren und Demonstratoren.
Unreal® und Unreal Engine® sind Marken oder eingetragene Marken von Epic Games, Inc. in den USA und anderswo; diese Artikel sind von Epic Games weder unterstützt noch geprüft. Project Chrono ist ein Open-Source-Projekt der University of Wisconsin-Madison und des Politecnico di Milano unter BSD-3-Lizenz.