Arbeitsschritte für HiRISE

Der gesamte code ist auf GitHub.com/luksab/HiRISE zu finden.

Planung

Storyboard

storyboard

Story

Der Protagonist steht von seinem Schreibtisch auf und schaut sich um - es starten Sirenen und er fängt an zum Fenster zu laufen. Auf dem Weg dahin wird er von mehreren Personen verfolgt und macht etwas Parkour über Tische und andere Hindernisse. Er bricht durch das Fenster und man sieht das Gebäude von außen, welches sich auf einem Science-Fiction Mars befindet und springt auf ein gegenübergelegenes Haus und läuft weg fällt in immer langsamer werdender Slow-Motion während die Kamera sich weiter bewegt.

Technisches

Features zu implementieren - in rot revidiert

  • Minimalistische Cinematic Engine
    • Datenformat aus Blender exportieren, in Programm importieren
      • einfach dae/obj
    • protobuf oder json als Dateiformat? - Custom (floats in Datei, space-separated)
    • Kameraposition, Skelettanimationen
      • Kamerapositionen speichen
  • Rigging für Charaktere
    • muss sehr gut funktion, um realistische Bewegungen zu erlauben
  • Physikalische Simulation der Glassplitter
    • kann auch wurde in Blender vorsimuliert werden, sollte es nicht in echtzeit möglich sein, da es aus Zeitgründen nicht möglich war.
  • Reflexion im Glas
    • Zunächst bei intakter Scheibe durch duplikation der Szene unsetzbar
    • Bei vielen Glassplittern andere Technik notwendig
      • Environment Map reflektieren
      • Environment Map in realtime neu erzugen - hier nicht notwendig, um gute Ergebnisse zu erzeugen.
    • z.B. SS (unvollständig), Ray-tracing (zu teuer), Environment Map
  • Dispacement Mapping + PDS Parser
    • Höhendaten und Bilder von Marsoberfläche aus PDS Daten laden
    • Marsoberfläche von HiRISE-daten
  • Sound
    • Etwas Musikunterlage
      • Code
      • Musik selbst

Optionale Features

  • Dynamische Subdivision Surface der Marsoberfläche
    • Erhöht sowohl Performance, als auch Qualität
  • Prozedurale Texturen für Mars-oberfläche
    • Farben für Flächen, auf denen die HiRISE Kamera keine Farbinformationen erhalten hat
    • ist nicht gut gelungen
  • HDR-Effekte, Bewegungsunschärfe, Fokusunschärfe
    • Qualität erhöhen, wenn noch Zeit und Performace über ist (Priorität absteigend)

Durchführung

Charakteranimation

Um die animation des Charakters realistisch zu gestalten wurden Referenzvideos aufgenommen, die dann in Blender als Hintergrund benutzt wurden, um dann mithilfe von inverse kinematics zu animieren. Blender Animation Die Referenzvideos sind mit der expliziten Erlaubnis von Ben Karcher aufgenommen und verwendet. Ben Karcher Erlaubnis

Marsoberfläche

Da als Umgebung eine Marsoberfläche gewünscht wurde, werden Höhendaten und ein Schwarz-Weiß Bild vom High Resolution Imaging Science Experiment (HiRISE, daher stammt auch der Projektname) benutzt. Der genaue Datensatz lässt sich unter https://www.uahirise.org/dtm/dtm.php?ID=ESP_048136_1725 finden.

Um aus den Höhendaten und dem Schwarz-Weiß Bild ein 3D-Objekt mit Farben zu erstellen wurde ein Referenzbild in Farbe benutzt, um ein Node-Netzwerk in Blender anzupassen, um nahe an das Referenzbild zu gelangen. Node-Netzwerk In Blender lassen sich in Echtzeit Parameter und Zusammenhänge ausprobieren um schnell zu iterieren und so zu einer Lösung zu kommen. Dieses Node-Netzwerk wurde dann in Shader-Code umgesetzt. Mars Shader

Mars in HiRISE gerendered

Mars Demo

Kamera und UI

Hier ist die Entwicklungsumgebung mit allen UI-Elementen aktiviert: Screenshot Demo Zur Entwicklung des Benutzerinterfaces wurde dear ImGui benutzt. Dies erlaubt schnell relativ komlexe Bedienelemente einzubinden. Die Entwicklung der einzelnen Elemente fand zum Großteil dadurch statt, dass eine Variable im Programm in Echtzeit verändert werden sollte, wodurch dann genau ein Element nötig wurde. Da diese Element jeweils also genau einen Verwendungszweck habem , lassen sie sich jeweils deaktivieren, um Platz zu sparen.

Kamerafahrt

Diese wird mithilfe von Splines, welche durch Punkte, durch die die Kamera gehen soll definiert werden. Hier ist die erste Kamerafahrt. Bei dieser sind die Tangenten noch nicht korrekt gesetzt, weswegen sie etwas abgehackt erscheint.

Die Punkte, durch die die Kamera gehen soll, werden in einem nach dem ersten Element von dem std::pair sortierten std::vector<std::pair<float, std::vector<float»> gespeichert. Es wird, um zwischen dem iten und (i+1)ten Punkt eine Kurve auszurechnen werden die Punkte i-1, i, i+1 und i+2 mit der globalen Zeit an eval übergeben. Diese rechnet dann zunächst die Steigungen der Kontrollpunkte von den Punkten p1 und p2 aus aus, welche p2-p0 und p3-p1 normiert entsprechen, wenn p1 zwischen p0 und p2 und p2 zwischen p1 und p3 liegt. Sonst werden die Kontrollpunkte auf die x-Koordinate beschränkt. Dies wird gemacht, damit Maxima und Minima eine symmetrischere Extremstelle aufweisen. spline code

PBR & HDRI

Außerhalb des Gebäude wird zur beleuchtung ein HDRI nach dem Vorbild von https://learnopengl.com/PBR/IBL/Specular-IBL benutzt. Außerdem werden die dort beschriebenen shader leicht verändert für die PBR-Objekte verwendet.

Skeletal animation

Das importieren von Skeletal Animationen hat sich als recht fragil herausgestellt und bei Exporteinstellungen, die von denen abweichen, die in blenderExport beschrieben werden, geht das Modell fast sicher kaputt.

Es werden die einzelnen Knochen rekursiv von der Hüfte aus importiert, indem die Transformationsmatrizen pro frame immer an die Kinder weitergegeben werden. Dadurch werden, wenn z.B der Arm bewegt wird die Hand und dadurch auch die Hand mitbewegt.

Hier ist der Anfang in Blender Animiert:

Spiegelung

Für den großen Spiegel mit Echtzeitreflexionen wird die Szene zwei mal gerendert. Ein mal normal und ein mal gespiegelt und mit einem Stencil auf die richtige Form zurechtgeschnitten. Dies geschieht in der main datei um Zeile 960.

Für die vielen kleinen Glasscherben wird lediglich die Environment Map reflektiert abgebildet. Dies geschieht vollständig im shader code.

Modelle

Mars

Da die Marsoberfläche vollständig aus Texturen entsteht, muss nur ein relativ hochaufgelöstes Quadrat eingeladen werden. Diese muss bereits einiges an Auflösung aufweisen, da meine Nvidia gtx 1070 ti leider nur 64 Tessellation levels unterstützt, was nicht ausreicht, um aus einem einzelnen Rechteck genug Detail herauszuhohlen. Die Farbtextur wird in einem Computeshader vorberechnet um zur Laufzeit Rechenleistung zu sparen. Dadurch lässt sich in der Szene beim Zeitpunkt der Implementation eine Performacesteigerung von nahezu 10x feststellen, da das berechnen der Farbinformationen sehr aufwendig ist.

Tisch, Stuhl, Bildschirm, USB-Stick

Diese Objekte wurden alle von mir in Blender modelliert, in dem Primitive zu einem Mesh zusammengefügt und dann teilweise leicht verändert wurden. Blender Modellierung

HiRISE Text

Der text wurde in Blender mithilfe des Text-Objektes ertellt. Dieses kann dann in Geometrie umgewandelt werden, die dann extrudiert wird, um ein dreidimensionales Objekt des ursprünglichen Textes zu erstellen.

Glasssplitter simulation

Der ursprüngliche Plan war es eine vollständige Simulation von Glass zu schreiben, die das Glas zersplittern und mit der Szene interagieren lassen sollte. Dies ist allerdings aus Zeitgründen nicht gelungen und wird jetzt durch das Blender Add-on Cell Fracture und die Ridgid Body Simulation von Blender ersetzt. Dort wird das Glas zunächst von Cell Fracture zersplittert und die einzelnen resultierenden Objekte interagieren dann miteinander und mit der Szene. eine Beispielkonfiguration von Cell Fracture shards

Extras

Shader auto-reload

Zum beschleunigen der Entwicklung von Shadercode wurde die Shaderklasse mit der Funktion reload, welche den Shadercode neuläd und checkReload, welche überprüft, ob die Datei seit dem letzten Laden/ Neuladen verändert wurde. Damit Lässt sich jeden Frame überprüfen, ob eine Datei verändert wurde, und wenn dies der Fall ist den zugehörenden Shader neuzuladen. Diese Schritte müssen allerdings mit einem Delay versehen werden, da das scheiben des neuen Shadercodes in die Datei etwas Zeit in anspruch nimmt. Die Funktion reloadCheck übernimmt diese Aufgabe und wartet 20ms, bevor der nächste Shader geladen wird. Das sorgt zwar dafür, dass die Frametime für einen Frame deutlich ansteigt, da aber nur in der Entwicklung und auch da im Vergleich zu der Gesamtzahl der gerenderten Bilder sehr selten die Shader neugeladen werden müssen, ist das ein Kompromiss, der sicherlich zu vertreten ist.

Prozedurale Texturen für Mars-oberfläche

Um die niedrige Piixeldichte auf der Mars-oberfläche zu mitigieren, wurde mithilfe des Shaderreloads mit Verschiedenen Typen von Noise experimentiert. Noise Die Ergebnisse lassen leider zu wünschen übrig und wurden deshalb nicht in das entgültige Video integriert.

Lukas Sabatschus

code, electronics und alles dazwischen


11.01.2022