Der gesamte code ist auf GitHub.com/luksab/HiRISE zu finden.
Planung
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
- Datenformat aus Blender exportieren, in Programm importieren
- Rigging für Charaktere
- muss sehr gut funktion, um realistische Bewegungen zu erlauben
- Physikalische Simulation der Glassplitter
-
kann auchwurde in Blender vorsimuliertwerden, 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
- Etwas Musikunterlage
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.
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.
Mars in HiRISE gerendered
Kamera und UI
Hier ist die Entwicklungsumgebung mit allen UI-Elementen aktiviert:
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.
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.
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.
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.