Aufgabe 2: Displacement

(Neue) Techniken:
Normal-Mapping, Parallax-Mapping, Displacement, Tangent-Space, Geometrie & Tessellation-Shader

Beschreibung:
In dieser Aufgabe sollen unterschiedliche Displacement Mapping Verfahren umgesetzt werden.
Als Einstieg soll das Pixel-basierte Normal Mapping und Parallax-Mapping implementiert werden, das anschließend mit Unterstützung der Tessellation-Funktionalität von OpenGL um eine Vertex-basierte Komponente erweitert wird. Der Fokus dieser Aufgabe liegt auf der Meso-Struktur der Oberfläche. Für die Beleuchtung soll weiterhin das Phong-Modell eingesetzt werden.

Es soll die in Aufgabe 1 angefertigte Lösung weiterverwendet werden.

Für die Bearbeitung dieser Aufgabe sollte OpenGL 4.0 und GLSL 4.0 (oder höher) verwendet werden. Tessellation ist erst ab 4.0 im Core von OpenGL.

Due Date: 25.11.2019

Erwartetes Render Ergebnis

Material

Die Lösung dieser Aufgabe müsst Ihr nicht von Grund auf neu schreiben oder ein Beispielprogramm abändern. Diese Aufgabe baut auf der Struktur von Aufgabe 1 auf.

Kernanforderungen

  • Die Tangent Spaces für die Vertices werden korrekt berechnet (beim Modell geladen). Die zweite Achse (Tangente oder Bitangente) wird gespeichert und die dritte wird im Shader mit dem Kreuzprodukt berechnet.
  • Die resultierende Normale wird anstelle der Geometrienormale (Normale der Makro-Struktur) für die Beleuchtungsberechnung verwendet
  • Es findet Geometrie Tessellation statt.

Weitere Funktionalitätsanforderungen

  • Für die Fläche soll der Tangent-Space korrekt berechnet werden. Für das Modell kann das Assimp-Flag gesetzt werden und der Modelloader um das einlesen der Tangenten (srcMesh->mTangents[i]) des Mesh ergänzt werden.Es soll korrektes Normalmapping und (Für das Grid) Parallax-Mapping umgesetzt werden.Beide Techniken soll mittels Tastendruckes jeweils umschaltbar sein.
  • Für das Parallax-Mapping soll die Technik Steep Parallax Mapping umgesetzt werden, da diese guten optischen Resultate liefert trotz stärkerer Rechenbelastung. Die Anzahl der Sample Ebenen soll abhängig vom Blickwinkel sein.
  • Es wird eine Punktlichtquelle ergänzt, die um die Szene bzw. Grundflache kreist (nahtloses Pausieren ist gefordert und ist hilfreich für optisches Debugging). Diese soll korrekt mit Abschwächung implementiert werden. (Siehe CG1).
  • Ein rudimentärer Tessellation Evaluation Shader ist implementiert und die Tessellation Level sind so eingestellt, dass eine Unterteilung der Patches stattfindet.
  • (Für das Grid) Der Tessellation Evaluation Shader wird verwendet, um die Positionen der Vertices entsprechend der übergebenen Displacement Map anzupassen. Dabei werden die Vertexpositionen entlang der Normale (nicht die Normale aus der Normal Map, sondern die Geometrienormale) verschoben. Die Normale für die Beleuchtung wird weiterhin durch das Normal Mapping ermittelt.
  • Der Tessellation Control Shader steuert die Tessellation Level abhängig von der Entfernung und Größe der Patches. Zusätzlich können weitere Parameter wie der Winkel der Oberfläche zum Betrachter einfließen. An den Patch-Kanten (zwischen den beiden Dreiecken) entstehen keine Löcher, d.h. für die äußeren Tessellation-Level wird für beide Kanten der Patches der gleiche Wert berechnet.
  • Die Tangenten, Bitangenten und Normalen werden mit einem Geometry Shader angezeigt. Um die verschiedenen Vektoren unterscheiden zu können, werden diese in unterschiedlichen Farben dargestellt. (Tangente = Rot, Bitangent=Grün, Normale=Blau) Die Bitangente soll im Shader berechnet werden, sodass lediglich die Normale und Tangente als Attribute an den Shader übergeben werden müssen.
  •        Geometry Instancing wird genutzt, um die zusätzliche Geometrie im Geometry Shader parallel zu erzeugen. Dabei werden keine Verzweigungsanweisungen oder Bedingungsoperatoren verwendet.
  • Die Lichtquelle soll visualisiert werden in der entsprechenden Lichtquellenfarbe. Dafür kann entweder ein Würfel oder eine Kugel gerendert. Diese Geometrien sollen wiederum keine Beleuchtung besitzen (Da diese Licht-Emitter sind).
  • In der Shading Stage „Normalmap“ soll diese nicht im Tangent-Space sondern konvertiert in den World-/Model-Space angezeigt werden.

    Tastatur-Belegung (Vorschlag):

    TASTEFUNKTIONBeschreibung
    ESCBeenden des Programms-
    F1Toggle Fullscreen-
    F2Tangent Space anzeigen an/ausDer Geometry Shader wird genutzt, um die Basisvektoren der Tangent Spaces anzuzeigen.
    F3Toggle WireframeRendern der Szene im Wireframe Modus
    F10Reload ShaderNeuladen der Shader (Bei Fehlern soll das Programm nicht abstürzen)
    1Toggle NormalmappingUmschalten der Nutzung des Normalmapping, ansonsten wird die interpolierte Geometrie-Normale verwendet
    2Toggle ParallaxmappingUmschalten Parallaxmapping, anonsten wird die Texturkoordinate verwendet
    3Toggle TessellationUmschalten Tessellation incl. Displacement, wenn eine Heightmap vorhanden ist
    H/hToggle HilfeAnzeige der Hilfe auf dem Bildschirm
    F/fToggle FPSAnzeige der Framerate auf dem Bildschirm
    G/gToggle Grid/SceneUmschalten zwischen Szene und Grid
    L/lToggle Licht VisualisierungUmschalten der Visualsierung der Lichtquelle
    N/nGrid Auflösung erhöhenErhöhen der Auflösung des Grids in der Hostanwendung (VBO)
    M/mGrid Auflösung verringernVerringern der Auflösung des Grids in der Hostanwendung (VBO)
    U/uDisplacement erhöhenDer Versatz der Vertices entlang der Normale wird erhöht
    I/iDisplacement verringernDer Versatz der Vertices entlang der Normale wird verringert.
    P/pPausierenZeitabhängige Animation pausieren
    S/sShading UmschaltenShading Umschalten
    STRG+LMBKamera Rotation(Absicherung für Gimbal Lock)
    STRG+MMBKamera Pan
    STRG+RMB (ggf. Mouse Wheel)Zoom Kamera (ggf. Versetzung entlang Orientierung)

    Shader (Vorschlag):

    Shader Komponenten Beschreibung
    LightVisShader Vertex & Fragment Zeichnet die Punkt-Lichtquelle als Primitive Geometrie (Cube oder Sphere)
    ModelShader Vertex & TessellationControl &   TessellationEvaluate & FragmentZeichnet das Modell bzw. das Grid mit den umschaltbaren Techniken Normalmapping, Parallaxmapping und Tessellation mit Displacement.
    SkyShader (Aufg 1)Vertex & FragmentZeichnet die Skymap im Hintergrund
    TangentShader Vertex & Geometrie & FragmentZeichnet die 3 Achsen des Tangent Spaces, es ist darauf zu beachten, dieselbe Berechnung wie beim ModelShader zu nutzen.
    TextShader (Aufg 1)Vertex & FragmentKann Text auf dem Display ausgeben

    Tipps

    • Die Scene besitzt keine Höhemap, aus diesem Grund müssen die davon Abhängigen Techniken (Vertex Displacement  & Parallax Mapping) nicht angewendet werden.
    • Es ist im Rahmen dieser Übung erlaubt bedingte Switches (if else) im Shader durchzuführen, obwohl dies nicht so effizient ist als verschiedene Shader zu bauen und bei Bedarf zu nutzen.
    • Hochauflösende Texturen (incl. Normal und Displacement-Maps) können hier [5] gefunden werden.
    • Achtet bei allen Matrix Multiplikationen auf die Reihenfolge! Die erste Transformation steht hinten (von rechts nach links). Auch bei einer Multiplikation mit einem Vektor muss die Reihenfolge beachtet werden. v*M führt nicht zu einem Compilerfehler, da GLSL nicht zwischen Zeilen und Spaltenvektoren unterscheidet. Es macht Sinn, das Koordinatensystem des/der Vektoren im Variablenname zu hinterlegen.
    • Normal Maps werden unter Umständen so gebaked (erstellt), dass der Nullpunkt nicht unten links, sondern oben links liegt. Berücksichtigt dies bei der Dekodierung der Normalen oder beim Transformieren aus dem Tangent Space, indem Ihr eine Achse invertiert.
    • Denkt daran, die Variable max_vertices im Geometry Shader zu erhöhen, falls Ihr mehrere Linien zeichnen wollt. Im Zusammenhang mit Geometry Instancing gibt max_vertices die Anzahl der emittierbaren Vertices pro Instanz an.
    • Wenn die Tessellation Level den Wert 0 haben, wird der Patch verworfen. Setzt diese am besten auf einen Wert >= 1 bevor Ihr anfangt, den Tessellation Evaluation Shader zu implementieren. Lasst Euch nicht von den verschiedenen Patch-Arten (Input, Ouput, Abstract) verwirren. Wir wollen uns auf die Grundlagen konzentrieren. Deswegen haben in dieser Aufgabe alle Patches 3 Vertices.
    • Für die Betrachter anhängige Tessellation kann die Funktion smoothstep nützlich sein. Diese kann auch mit einem höheren Wert für edge0 als für edge1 aufgerufen werden. Ihr könnt jedoch auch beliebige andere Interpolationen wählen.
    • Um den Abstand zur Kamera für die Betrachter abhängige Tessellation zu berechnen, benötigt Ihr die Kameraposition im Weltkoordinatensystem. Diese könnt Ihr berechnen, indem Ihr die inverse View-Matrix mit dem Nullpunkt (0, 0, 0, 1) multipliziert. Matrixinvertierungen werden im Shader vermieden. Sie können im Host vorberechnet werden, um eine höhere Performance zu erreichen. Im Praktikum müsst Ihr auf solche Feinheiten nur bedingt Rücksicht nehmen. Wählt den übersichtlicheren Weg, solange sich dies nicht stark Negativ auf die Performanz des Programmes auswirkt.
    • Wenn Ihr die Betrachter abhängige Tessellation implementiert, kommt es zu einem Flackern der Geometrie. Hierfür gibt es Lösungen, die jedoch zusätzlichen Implementierungsaufwand mit sich ziehen. Um dieses Problem zumindest etwas weniger auffällig zu machen, könnt Ihr die Unterteilungsstrategie auf fractional_odd_spacing oder fractional_even_spacing setzen oder die Stärke des Versatzes entlang der Normale vom Abstand abhängig machen. Dies ist jedoch nicht gefordert.
    • Ihr könnt Euch als Hilfe eine Shading Stage im Fragment-Shader ergänzen für Displacement Maps. Achtet darauf ob ihr Height- oder Depthmaps ladet!
    • Eine Normale bzw. Tangente ist ein Einheitsvektor, zur Optimierung kann jeweils die 3. Komponente auf der GPU berechnet werden.
    • Folgende Beispiel können behilflich sein:
      Geometry Shader (zip auf HP), demoTessellation

    Brick-Textur

    Keine Technik (Phong Shading & Geo Normal)
    Normal Mapping
    Parallax Mapping
    Normal & Parallax Mapping

    Stone Texture

    Grid Render
    Tessellation Far
    Tessellation Near

    Szene

    Scene Render
    Normalmap im World Space (Tangent to World Space Transformation)
    Tessellation mit Faktor durch Abstand und Patch Größe
    Anzeige des Tangentspaces mithilfe des Geometrie Shader und Geometrie Instancing

    Ideen

    Für diejenigen, die mit der Aufgabe schnell fertig und noch nicht genug ausgelastet mit CG2 und anderen Übungen sind, gibt es folgende Ideen, die zum Teil das Wissen vertiefen oder einen Vorausblick auf die kommenden Aufgaben geben können.

    • Für die Szene können aus den Normalmaps bzw. Diffuse Maps mit vorheriger Filterung Heightmaps erstellt werden, sodass das Parallax Mapping und das Vertex Displacement im Tessellation Evaluation Shader auch für die Szene durchgeführt werden können. Es kann auch probiert werden, diese zur Laufzeit beim Laden der Texturen zu generieren.
    • Es können verschiedene Arten von Parallax Mapping implementiert werden z.B. Reliefe Parallax Mapping & Parallax Occlusion Mapping. Beide könne die Szene optisch verbessern.
    • Nutzung mehrerer Lichtquellen. Gerade im Vergleich zu der Fixed-Function Pipeline, kann man sehen, dass sich die Lichtberechnung und das Setzten von Lichtquellen unterscheidet und gerade die Lichtquellen geben einer einfachen 3D Szene ein realistisches Erscheinungsbild. Warum also nicht unsere Szene erleuchten?
    • Es können auch weitere bzw. andere Modelle in unsere Szene geladen werden.
    • Nutzung von Instancing für verschiedene selbe Strukturen (siehe Vorlesungs- Folien).
    • Nutzung einer Noise-Funktion anstelle einer Displacement-Map (dies wird oft in 3D-Programmen wie Maya oder Cinema4D für das Displacement genutzt)
    • ....

    Links & Source:

    [1] @misc{ORCAAmazonBistro,
                     title = {Amazon Lumberyard Bistro, Open Research Content Archive (ORCA)},
                     author = {Amazon Lumberyard},
                     year = {2017},
                     month = {July},
                     note = {\small \texttt{http://developer.nvidia.com/orca/amazon-lumberyard-bistro}},
                     url = {http://developer.nvidia.com/orca/amazon-lumberyard-bistro}
                     }

    [2] http://www.assimp.org/

    [3] https://docs.microsoft.com/de-de/windows/win32/direct3ddds/dds-header
    https://www.oldunreal.com/editing/s3tc/ARB_texture_compression.pdf

    [4] https://hdrihaven.com/

    [5] https://texturehaven.com/

    Abnahme

    UhrzeitJonasDennisEduard
    8:00
    8:301341
    9:001272
    9:30
    10:0056

    3

    10:30