Computer Graphik - Wasser mit Tessellierung
Computer Graphik - Wasser mit Tessellierung
Computer Graphik - Wasser mit Tessellierung
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
<strong>Computer</strong> <strong>Graphik</strong> - <strong>Wasser</strong> <strong>mit</strong> <strong>Tessellierung</strong><br />
Praktikum <strong>Computer</strong> <strong>Graphik</strong> im WS 2012/13 bei Prof. Eisert<br />
Joanathan Bräuer<br />
Marvin Triebel<br />
1 Beschreibung des Programms<br />
Es wurde ein Programm geschrieben, dass durch den Einsatz der OpenGL Pipieline <strong>mit</strong> dem Tessellation<br />
Shader eine <strong>Wasser</strong> Oberfläche erzeugt. Das <strong>Wasser</strong> bewegt sich dynamisch und durch einen Klick breitet<br />
sich eine Welle von der Klickposition aus. Dabei werden viele Berechnungen für die <strong>Wasser</strong>oberfläche auf<br />
der Grafikkarte durchgeführt.<br />
Abbildung 1: Das fertige Programm<br />
Das Programm wurde für OpenGL geschrieben und funktioniert nur auf Windows. Zudem ist es<br />
erforderlich, dass die Grafikkarte den Tessellation Shader unterstützt.<br />
2 Realisierung<br />
Im folgenden werden die einzelnen Schritte der Realisierung beschrieben.<br />
1
2.1 Erstellung des Basisprogramms<br />
Als erstes wurde auf Grundlage von [2] ein ausführbares Programm erstellt <strong>mit</strong> der OpenGL 3.0 Pipeline<br />
inklusive Tessellation Shader. Als einziges sichtbares Objekt ist eine Fläche zu sehen.<br />
Abbildung 2: Die Szene ohne Tesselierung als Wireframe<br />
2.2 <strong>Tessellierung</strong><br />
Als nächstes wurde die Tessellation Pipeline <strong>mit</strong> dem Tessellation Control und dem Tessellation Evaluation<br />
Shader geschrieben, um dynamisch neue Vertices zu erzeugen.<br />
Abbildung 3: Vergleich: Polygonnetz ohne <strong>Tessellierung</strong> und Polygonnetz <strong>mit</strong> <strong>Tessellierung</strong> (16 Inner/16<br />
Outer)<br />
2
2.3 Erzeugung der Welle<br />
Die Welle wurde nach Abhängigkeit in Lage der Ebene und der Zeit <strong>mit</strong> folgender Formel erzeugt. Die<br />
Gewichtungen wurden durch Ausprobieren herausgefunden.<br />
d = √ x 2 + z 2<br />
δ = d − t<br />
{<br />
0 , falls δ > 0<br />
y(δ) =<br />
15<br />
0.1 · sin(2 · δ) ·<br />
15+δ<br />
, sonst<br />
1.5<br />
wobei x und z der Abstände zum Wellenzentrum in der Ebene und t die vergangene Zeit seit Beginn der Welle ist<br />
Die Normale konnte dann entsprechend der Ableitung berechnet werden.<br />
⎧⎛<br />
⎞<br />
⎜<br />
⎝<br />
⎛<br />
⎪⎨<br />
⎜<br />
n(x, y) = ⎝<br />
x<br />
d<br />
−1<br />
y ′ (δ)<br />
z<br />
d<br />
−x<br />
d<br />
1<br />
y ′ (δ)<br />
−z<br />
⎟<br />
⎠ , falls y ′ (x) < 0<br />
⎞<br />
⎟<br />
⎠ , falls y ′ (x) < 0<br />
⎛ ⎞d<br />
0<br />
⎜ ⎟<br />
⎝1⎠ , falls y ′ (x) = 0<br />
⎪⎩<br />
0<br />
Abbildung 4: Die Welle ohne Normalen-Noise und ohne Cubemap<br />
3
2.4 Erkennen der Klickposition<br />
Um das Wellenzentrum an der Stelle zu positionieren, an die geklickt wurde, mussten wir die Position<br />
des Mauszeigers in einen Ray umwandeln. Dafür haben wir die Position des Mauszeigers im Viewport<br />
auf die Near- und Far-Clipping Plane übertragen und so<strong>mit</strong> einen Ray erzeugt. Nun suchten wir den<br />
Schnittpunkt dieses Rays <strong>mit</strong> der Ebene E : {(x, y, z)|y = 0} und konnten so den Punkt hinter dem<br />
Mauszeiger er<strong>mit</strong>teln, an dem sich das Wellenzentrum befinden sollte.<br />
2.5 Verwenden von Noise<br />
Für eine rauhe Oberfläche des <strong>Wasser</strong> wurden die Normalen des <strong>Wasser</strong> durch Einsatz von Simplex<br />
Noise[4] jeweils ein wenig variiert. Das Simplex Noise wurde in Abhängigkeit der Position in der Ebene<br />
sowie der Zeit berechnet. Die Implementation wurde von [4] übernommen.<br />
Ähnlich zu dem Noise auf den Normalen wurde auch die Geomtrie durch den Einsatz von Simplex<br />
Noise ein wenig variiert, sodass die Oberfläche des <strong>Wasser</strong> stets in Bewegung ist. Allerdings sind bei der<br />
Ebene die Veränderungen auf der Geometrie weniger gravierend. Die meisten sichtbaren Veränderungen<br />
wurden durch das Noise auf den Normalen erreicht.<br />
2.6 Lichtberechnung<br />
Es wird nur eine Punktlichtquelle eingesetzt, die ähnlich einer Abendsonne nah über dem <strong>Wasser</strong> steht<br />
und ein gelbrotes Licht wirft. Die Lichtfarbe und Reflektion wurde nach dem Blinn-Phong-Modell[2]<br />
berechnet. Zusätzlich wurde ein blaues Licht hinzugefügt, das ambient leuchtet.<br />
2.7 Reflektion durch Cubemap<br />
Abbildung 5: Das Licht der Szene im Normalennoise<br />
Um Reflektionen auf dem <strong>Wasser</strong> zu simulieren, wurde zusätzlich eine Cubemap eingesetzt. Die Cubemap<br />
wurde von [1] genommen.<br />
4
2.8 Alphatransparenz <strong>mit</strong> Untergrund<br />
Abbildung 6: Die Reflektionen der Cubemap <strong>mit</strong> Noise<br />
Durch Verwendung der entsprechenden OpenGL Funktionen wurde die <strong>Wasser</strong>oberfläche halbtransperent<br />
gemacht. Zusätzlich wurde eine <strong>mit</strong> Kieselsteinen texturierte Ebene unter dem <strong>Wasser</strong> eingefügt.<br />
5
2.9 Performanz<br />
Abbildung 7: halbe Transparenz des <strong>Wasser</strong>s<br />
Durch den Einsatz von Tesselierung ließ sich eine gute Performance bei hoher Detailstufe erreichen. Als<br />
Testrechner wurde AMD Athlon II 3Ghz QuadCore <strong>mit</strong> 8GB Ram und einer nVIDIA Geforce GTX 550ti<br />
Grafikkarte <strong>mit</strong> 1024MB DDR Grafikspeicher verwendet. Hier wurde <strong>mit</strong> dem Beispielprogramm bei einer<br />
Auflösung von 800x600 und einem Tesselierungsfaktor von 40 (sowohl Inner als auch Outer Tesselation)<br />
eine Renderzeit von rund 3-4ms (ca. 30 FPS) erreicht. Die Basisebene besteht aus 576 Vertices. Durch<br />
Tesselierung wurden dabei etwa 2,8 Millionen neue Vertices erzeugt.<br />
3 Weitere Ideen, Schlussfolgerungen<br />
Der Einsatz von Noise und Wellen im Tessellation Shader ist ein mächtiges Werkzeug, um Oberflächen<br />
durch zusätzliche Vertices natürlicher wirken zu lassen bei sehr guter Ressourcenausnutzung durch die<br />
Berechnung auf der Grafikkarte.<br />
3.1 Erweiterungsideen<br />
Für das Programm gab es folgende Ideen als mögliche Erweiterungen:<br />
6
• Abstandsabhängige Tesselierung<br />
Die Anzahl der eingefügten Vertices könnte in Abhängigkeit des Abstandes und des Winkels zur<br />
Betrachterposition variiert werden. Dadurch müssten weniger Punkte tesseliert werden und die<br />
Performance ließe sich steigern.<br />
• andere Noisefunktionen Durch den Einsatz von den anderen Noisefunktionen oder speziellen<br />
Normalmaps könnte die rauhe Oberfläche des <strong>Wasser</strong> natürlicher wirken.<br />
• Lichtbrechung Das Licht sollte eigentlich von dem <strong>Wasser</strong> gebrochen werden und durch Berechnung<br />
des Brechungswinkels könnte ein Refraction- Effekt erreicht werden. Um auf Raytracing zu verzichten<br />
könnte der flache Untergrund vorher einmal gerendert werden, um dann durch Verwendung der<br />
Normalen des <strong>Wasser</strong>s die Brechung zu berechnen.<br />
• mehrere Wellen überlagern Das Programm kann zu einem Zeitpunkt nur eine Welle um ein<br />
Zentrum darstellen. Eine Möglichkeit das Programm zu erweitern wäre mehrere Wellen zu überlagern.<br />
Dadurch würden sich die Berechnung der Sinuswellen überlagern und die Berechnung der Normalen<br />
durch die Ableitung müsste entsprechend angepasst werden, um die überlappenden Wellen zu<br />
berechnen.<br />
Literatur<br />
[1] afgho (Cafu). “Skybox creation (Environmental Map, Cubemap)”. 2013. url: http://www.cafu.<br />
de/wiki/textures:skydomes.<br />
[2] Prof. Dr. Peter Eisert. “Halbkurs <strong>Computer</strong> <strong>Graphik</strong>”. 2012. url: http://www.informatik.huberlin.de/forschung/gebiete/viscom/teaching/computergraphik12.<br />
[3] Jeff Molofee (NeHe) Evan Pipho (Terminate). “Loading Compressed And Uncompressed TGA’s”.<br />
2013. url: http://nehe.gamedev.net/tutorial/loading_compressed_and_uncompressed_tga%<br />
27s/22001/.<br />
[4] Ashima Arts Ian McEwan. “Array and textureless GLSL 2D/3D/4D simplex noise functions”. 2011.<br />
url: https://raw.github.com/ashima/webgl-noise/master/src/noise3D.glsl.<br />
7