Echtzeitfähige Simulation von Wasser auf Grafikhardware

Transcription

Echtzeitfähige Simulation von Wasser auf Grafikhardware
Technische Universität München
Fakultät für Informatik
Diplomarbeit
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Thomas Schiwietz
Aufgabensteller:
Prof. Dr. Rüdiger Westermann
Betreuer:
Dipl.-Inf. Jens Krüger
Abgabedatum:
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 2 von 99
Ich versichere hiermit, dass ich diese Diplomarbeit selbständig verfasst und nur die
angegebenen Quellen und Hilfsmittel verwendet habe.
Datum
Unterschrift
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 3 von 99
Echtzeitfähige Simulation von Wasser auf Grafikhardware
1. Einleitung..........................................................................................5
1.1.
Das Potential moderner Grafikkarten............................................... 5
1.1.1.
1.1.2.
1.1.3.
1.2.
Die feste Pipeline herkömmlicher Grafikkarten ..................................... 5
Freie Programmierbarkeit durch Vertex- und Pixel-Shader................... 6
Neue Anwendungsfelder für Grafikkarten mit Shadern ......................... 7
Ziele dieser Diplomarbeit................................................................... 8
2. Simulation von Wasseroberflächen ...............................................9
2.1.
Die Wellengleichung .......................................................................... 9
2.1.1.
2.1.2.
2.1.3.
2.1.4.
2.1.5.
2.1.6.
2.2.
Modellierung des Lichts .................................................................. 19
2.2.1.
2.2.2.
2.2.3.
2.2.4.
2.3.
Die partielle Differentialgleichung.......................................................... 9
Diskretisierung der Differentialgleichung ............................................. 11
Diskretisierung der Membran .............................................................. 13
Numerische Stabilität .......................................................................... 14
Dämpfung ........................................................................................... 15
Einschläge von Objekten auf die Wasseroberfläche ........................... 16
Berechnung der Normalen der Wasseroberfläche .............................. 19
Lichtfarbe und Lichtintensität (Phong-Illumination-Model)................... 22
Lichtreflexion ....................................................................................... 25
Lichtbrechung...................................................................................... 28
Implementierung .............................................................................. 31
2.3.1.
2.3.2.
2.3.3.
Lösung der Wellengleichung in Grafikhardware.................................. 31
Zweidimensionale Darstellung ............................................................ 33
Dreidimensionale Darstellung ............................................................. 35
3. Simulation von Fluiden..................................................................37
3.1.
Die inkompressiblen Navier-Stokes-Gleichungen ........................ 37
3.2.
Diskretisierung ................................................................................. 42
3.2.1.
3.2.2.
3.2.3.
3.2.4.
3.2.5.
3.3.
Das Gebiet .......................................................................................... 42
Hindernisse ......................................................................................... 44
Die Zeit, das Stabilitätskriterium.......................................................... 45
Die Impulsgleichung............................................................................ 46
Die Kontinuitätsgleichung.................................................................... 49
Der Algorithmus ............................................................................... 50
3.3.1.
3.3.2.
3.3.3.
Die Berechnung der Diffusion und Konvektion.................................... 50
Die Berechnung des Drucks................................................................ 51
Der gesamte Algorithmus.................................................................... 54
Echtzeitfähige Simulation von Wasser auf Grafikhardware
3.4.
Implementierung .............................................................................. 55
3.4.1.
3.4.2.
3.4.3.
3.4.4.
3.4.5.
3.4.6.
3.4.7.
3.5.
Texturen .............................................................................................. 55
Vertex-Buffer ....................................................................................... 57
Die Shader-Programme ...................................................................... 59
Die Rendering Pipeline ....................................................................... 62
Ein Beispiel Shader in HLSL: ImpulseF .............................................. 64
Visualisierung...................................................................................... 69
Geschwindigkeitsmessungen.............................................................. 76
Simulierte Probleme......................................................................... 79
3.5.1.
3.5.2.
3.5.3.
3.5.4.
3.5.5.
3.6.
Seite 4 von 99
Nischenströmung ................................................................................ 79
Kármánsche Wirbelstraße................................................................... 81
Stufenströmung................................................................................... 83
Strömung über ein Auto ...................................................................... 85
tum3D-Logo ........................................................................................ 86
Erweiterungen .................................................................................. 87
3.6.1.
3.6.2.
3.6.3.
3.6.4.
3.6.5.
3.6.6.
3.6.7.
Visualisierung...................................................................................... 87
Stromfunktion ...................................................................................... 87
Hinderniseditor .................................................................................... 88
Numerische Fehler.............................................................................. 88
Freie Randwertprobleme..................................................................... 89
Temperatur (Energietransport)............................................................ 89
Dreidimensionale Navier-Stokes-Gleichungen.................................... 90
4. Fazit .................................................................................................92
Literaturverzeichnis .............................................................................93
Abbildungsverzeichnis ........................................................................95
Stichwortverzeichnis ...........................................................................97
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 5 von 99
1. Einleitung
1.1. Das Potential moderner Grafikkarten
In den letzten Jahren gab es große Fortschritte in der Entwicklung der Grafikkarten.
Neben immer höheren Dreiecksdurchsatzraten, reicht auch der Video-Speicher
schon fast an die gleiche Größenordnung wie der Hauptspeicher des Systems heran.
Die interessantesten Neuerungen sind seit den letzten Kartengenerationen vor allem
die so genannten Vertex- und Pixel-Shader. Shader sind freiprogrammierbare Prozessoren, die Teil der GPU (Graphical Processing Unit) sind. Bisher war die GPU
fest verdrahtet, was zur Folge hatte, dass der eingehende Datenstrom aus Vektorund Texturdaten fest vorgegebene Wege durchlief.
1.1.1. Die feste Pipeline herkömmlicher Grafikkarten
Die wesentlichen Stationen der festen Pipeline sehen typischerweise wie folgt aus: In
der Geometrieverarbeitungsstufe werden auf die dreidimensionalen Vektoren die
Welt- und Kameramatrix multipliziert und schließlich auf ein zweidimensionales Raster, den Bildschirmspeicher, projiziert.
Im Anschluss wird die zweidimensionale Geometrie gerastert. Pro Pixel werden Texturzugriffe und Lichtberechnungen durchgeführt, die nur sehr eingeschränkt programmierbar sind. Dazu stehen wenige einfache Operationen wie Addition oder Multiplikation zweier Texturen zur Verfügung.
Abbildung 1: Schematischer Aufbau der Hardware
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 6 von 99
1.1.2. Freie Programmierbarkeit durch Vertex- und Pixel-Shader
Mit Hilfe der Shader kann die GPU einer modernen Grafikkarte frei programmiert
werden. Es gibt zwei Arten von Shader, zum Einen die Vertex-Shader, die die Geometrieverarbeitung programmierbar machen, und zum Anderen die Pixel-Shader, die
die Rasterung der Pixel, der einzelnen Fragmente, programmierbar machen.
Vertex-Shader sind auf die Berechnung geometrischer Funktionen spezialisiert. Dazu
zählen beispielsweise mathematische Operationen wie das Produkt aus Matrix und
Vektor, Skalarprodukte, Vektorprodukte, Längenbestimmung und Normalisierung von
Vektoren. Ebenso können viele trigonometrische Funktionen wie Sinus, Cosinus oder
die Exponentialfunktion berechnet werden. Im Gegensatz zum Hauptprozessor stehen für die meisten dieser Operationen eigene Hardwarebausteine zur Verfügung,
die die Ausführung in einem Takt vollziehen können. Typische Einsatzgebiete von
Vertex-Shadern sind neben der freien Verformung von Geometrien, Beleuchtungsund Schattenberechnungen.
Pixel-Shader sind dazu da, Texturdaten zu laden und zu verarbeiten. Als Ergebnis
eines Pixel-Shaders werden eine Farbe und ein Tiefenwert zurückgegeben, die ein
Bildpunkt annehmen soll. Moderne Grafikkarten können bis zu acht Texturen pro
Dreieck auslesen und verarbeiten. In den Texturen können Grafiken, Lichtverteilungen, Oberflächennormalen oder beliebige Daten abgespeichert werden, die zur Berechnung einer realistischen Oberfläche notwendig sind. Durch die freie Programmierbarkeit der Pixel-Shader können die Texturen an jeder Stelle ausgelesen und mit
Hilfe von Registern, wie man es auf dem Hauptprozessor gewohnt ist, zwischengespeichert werden. Darauf können alle grundlegenden mathematischen Operationen
angewendet werden um so beispielsweise aufwändige Lichtmodelle, wie das PhongShading-Model, im Pixel-Shader zu berechnen.
Abbildung 2: Aufbau einer Grafikkarte
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 7 von 99
1.1.3. Neue Anwendungsfelder für Grafikkarten mit Shadern
Eigentlich wurden die Vertex- und Pixel-Shader dazu entwickelt, flexible geometrische Modelle zu programmieren und schwer darstellbare Oberflächen optisch wiederzugeben, wie zum Beispiel Rost, der sich im Lauf der Zeit in eine Autotür frisst. In
der Spieleindustrie werden diese Eigenschaften ausgenutzt.
Die flexible Programmierbarkeit der Shader lässt sich auch zweckentfremden, um
beliebige mathematische Probleme von der Grafikkarte berechnen zu lassen. Sobald
man das Ziel eines Renderingpasses nicht mehr auf die Bildschirmausgabe, sondern
auf eine Textur im Video-Speicher setzt, lassen sich die Texturwerte als Variablen
eines Arrays verwenden. Durch Hintereinanderausführung mehrerer Renderingpasses können Texturen in mehreren Stufen als Lese- und Schreibziele verwendet werden. In den Projekten dieser Diplomarbeit wurde diese Fähigkeit der Pixel-Shader
ausgenutzt.
Abhängig von der GPU lassen sich Texturen mit Fließkommawerten nach dem IEEE
float – Standard anlegen und für sehr genaue Berechnung verwenden. Zurzeit unterstützen die großen Kartenhersteller Fließkommatexturen zwischen 16- und 32-bit
pro Komponente. Dies reicht zwar nicht an die Genauigkeit der 64-bit Fließkommaeinheit im Hauptprozessor heran, lässt sich aber für erste Versuche verwenden.
Bevor man diese Idee weiterverfolgt, stellt sich die Frage, aus welchem Grund man
denn eine Grafikkarte zur Berechnung von grafikfremden Problemen verwenden sollte.
Die Antwort liegt in der hohen Verarbeitungsgeschwindigkeit der Grafikkarten. Durch
ihre vektorrechnerähnliche Struktur sind Shader Parallelrechner, die einerseits Operationen auf Vektoren mit vier Komponenten parallel ausführen können und andererseits selbst mehrfach auf der Grafikkarte vorhanden sind. Aktuelle Karten besitzen
teilweise bis zu acht Pixel-Shader-Einheiten, die parallel geschaltet sind.
Neben der parallelen Auslegung der Shader-Einheiten ist die sehr schnelle Anbindung zum Video-Speicher der Grafikkarten ein Geschwindigkeitsvorteil gegenüber
der CPU. Im Video-Speicher werden Geometrie-Daten, Texturen und ShaderProgramme, sowie der Bildschirmspeicher abgelegt, der das Ausgabebild für den
Monitor liefert (siehe Abbildung 2).
Auf alle diese Daten kann ohne Umweg über den System-Bus sehr schnell zugegriffen werden. Bei der Initialisierung eines Programms kann man – soweit schon verfügbar – alle notwendigen Daten vom Hauptspeicher in den Video-Speicher kopieren, damit der System-Bus zur Laufzeit durch Datentransfer nicht mehr belastet wird.
Wenn neben einer mathematischen Berechnung anschließend eine Visualisierung
der Ergebnisse ansteht, werden unnötige Bustransfers über das System vermieden.
Neben den oben genannten Vorteilen hält das hohe Tempo der Weiterentwicklung
der Karten weiter an, was künftig zu weiteren Geschwindigkeitszunahmen führen
wird. Etwa zweimal im Jahr stellen die großen Grafikkartenhersteller ihre neue GPUGeneration vor, die ihre Vorgänger meist deutlich übertrifft.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 8 von 99
1.2. Ziele dieser Diplomarbeit
Im Rahmen dieser Diplomarbeit werden zwei Anwendungsbeispiele zur numerischen
Simulation von Wasser und Fluiden auf Grafikhardware vorgestellt.
Das Ziel besteht darin, die gesamten numerischen Berechnungen von der Grafikkarte durchführen zu lassen. Bei Initialisierung der Programme werden alle notwendigen
Daten in den Video-Speicher kopiert und zur Laufzeit darf die CPU nur ShaderProgramme auf der GPU aufrufen. Arbeitslos ist die CPU trotzdem nicht, weil sie sich
um die Nachrichten-, Maus- und Fensterverwaltung des Programms kümmern muss.
Die numerische Berechnung erfolgt aber ausschließlich auf der GPU.
Als erstes Teilprojekt geht es um die Umsetzung der allgemeinen Wellengleichung
zur Simulation von Wasseroberflächen. Hierbei wird ein membranartiges Gitternetz
simuliert, das zum Beispiel von Regentropfen ausgelenkt wird und anschließend
nach den Gesetzen der Wellengleichung ausschwingt. Neben der Berechnung der
Wellen werden Lichtberechnungen durchgeführt, die die optische Qualität steigern.
Im Rahmen dieser Diplomarbeit wurde nur eine explizite Lösung der Wellengleichung
implementiert.
Im zweiten Teilprojekt geht es um die Simulation von Strömungen. Dazu werden die
inkompressiblen Navier-Stokes-Gleichungen diskretisiert und auf der Grafikkarte berechnet. Aus Performancegründen wird nur der zweidimensionale Fall betrachtet,
eine Erweiterung ins Dreidimensionale ist aber relativ einfach zu programmieren.
Beide Projekte basieren gänzlich auf Pixel-Shader Programmen. Vertex-Shader Programme zur Geometrieverarbeitung werden nicht benötigt, weil alle Berechnungen
auf zweidimensionalen Arrays bzw. Texturen ausgeführt werden.
Das Ziel der beiden Projekte lag in erster Linie darin, die Möglichkeiten und die Geschwindigkeit moderner Grafikkarten mit Shadern auszuloten. Es geht nicht um eine
numerisch exakte Lösung, die mit einer Implementierung auf der CPU oder FPU mithalten kann. Dazu fehlen vor allem Fließkommaformate mit hoher Genauigkeit. Es
ging darum zu zeigen, dass Grafikkarten heutzutage in der Lage sind mathematische
Probleme in sehr hoher Geschwindigkeit zu berechnen – wenn auch nicht mit der
Genauigkeit von FPUs. Allerdings entwickeln die Hersteller ihre Karten im ungebremsten Wettbewerb stetig weiter, so dass es nur eine Frage der Zeit ist, bis dieses
Problem vernachlässigbar ist.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 9 von 99
2. Simulation von Wasseroberflächen
Im Folgenden wird ein Algorithmus zur Lösung der allgemeinen Wellengleichung auf
Grafikhardware vorgestellt. Der hier gewählte Ansatz simuliert eine Wasseroberfläche, die man sich wie eine Membran vorstellen kann. Sie kann durch Regentropfen
oder Gegenstände, die ins Wasser geworfen werden, ausgelenkt werden. Durch die
Gesetze der Wellengleichungen beginnt daraufhin diese Membran zu schwingen,
wobei sich charakteristische Wellen ausbreiten, wie man es von realem Wasser
kennt.
Dieser Ansatz simuliert kein Volumen, sondern nur eine Oberfläche. Die Membran ist
also unendlich dünn und „darunter“ ist nichts. Außerdem werden hier nur stille Gewässer simuliert, Strömungen werden im nächsten Teilprojekt im Kapitel 3 ab Seite
37 behandelt.
2.1. Die Wellengleichung
2.1.1. Die partielle Differentialgleichung
Ausgangspunkt ist die zweidimensionale Poisson-Gleichung, die eine Vielzahl von
physikalischen Problemen beschreibt, je nach dem, wie die rechte Seite der PoissonGleichung f ( x, y ) gewählt wird. Neben der Temperaturverteilung in isotropen Medien im Gleichgewichtszustand oder das erzeugte elektrische Potential durch eine
Ladungsverteilung, kann auch eine Membran damit berechnet werden.
∂ 2 u ( x , y ) ∂ 2 u ( x, y )
= f ( x, y )
+
∂y 2
∂x 2
In [10], [11], [12] und [13] finden sich Herleitungen aus den Wärmegesetzen, numerische Lösungsverfahren und zahlreiche Anwendungsbeispiele.
Um eine Membran zu simulieren, benötigt man als rechte Seite die zweite partielle
Ableitung nach der Zeit t.
 ∂2 y ∂2 y  ∂2 y
c  2 + 2  = 2
∂z  ∂t
 ∂x
2
Die allgemeine Wellengleichung beschreibt, wie sich die Membran in einem bestimmten, unendlich kleinen Punkt verhält. Die Nachbarn eines Punktes nehmen dabei unmittelbaren Einfluss auf die Auslenkung, da durch die Oberflächenspannung
benachbarte Punkte zusammengehalten werden. Wenn also ein Punkt durch den
Einschlag eines Regentropfens oder eines Steines nach unten ausgelenkt wird, so
beeinflusst das auch seine Nachbarn, die dann auch heruntergezogen werden. Im
nächsten Iterationsschritt pflanzt sich diese Entwicklung fort und es entstehen Wellenbewegungen. Durch die gegenseitige Ausgleichung der horizontalen Kräfte, kann
sich ein Punkt der Membran nur auf und ab bewegen, jedoch niemals seitwärts.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 10 von 99
Um die partielle Differentialgleichung lösen zu können benötigt man Anfangswerte
und Randbedingungen. Eine gültige Ausgangslage ist eine ruhende Membran, die an
jedem Ort nicht ausgelenkt ist. Hier wurde ein Wasserbecken simuliert, so dass für
die Randbedingung gilt, dass die Wellen am Rand in das Becken zurück reflektiert
werden.
Zunächst zur Erklärung der Variablen. Die geometrischen Achsen verlaufen so, dass
die z-Achse die Tiefe in den Raum repräsentiert und die y-Achse die Höhe. Die
Membran erstreckt sich über die x- und z-Achse und kann entlang der y-Achse nach
oben und unten ausgelenkt werden.
Abbildung 3: Membran und Koordinatenachsen
Über die Variable t, die die Zeit darstellt, lässt sich die gesamte Simulation schneller
oder langsamer ablaufen lassen. Im Gegensatz zur Zeit t bestimmt die Wellengeschwindigkeit c, wie schnell sich die Wellen über die Membran ausbreiten. Der Unterschied zwischen t und c liegt darin, dass die Zeit t ein globaler Parameter ist und
sich auf die gesamte Membran auswirkt. Dagegen kann die Wellengeschwindigkeit c
als lokaler Parameter aufgefasst werden. Durch Anpassung von c kann man an unterschiedlichen Stellen unterschiedliche Medien entsprechend ihrer Durchflussgeschwindigkeit bzw. Wasserdurchlässigkeit simulieren.
Im Allgemeinen kann die Wellengleichung nicht in analytischer Form gelöst werden.
Deswegen wird sie im folgenden Abschnitt durch ein geeignetes numerisches Verfahren diskretisiert.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 11 von 99
2.1.2. Diskretisierung der Differentialgleichung
Um die Wellengleichung zu diskretisieren werden finite Differenzenverfahren angewendet. Mit Hilfe der Taylor-Formel lassen sich für partielle Ableitungen verschiedener Ordnungen finite Differenzen bestimmen. Als Grundlage dient die Taylor-Formel,
wobei R das Restglied der eigentlich unendlichen Reihe darstellt.
f ' (a)
f (n )
(x − a ) + L +
(x − a )n + Rn+1 (x − a )
f ( x) = f (a) +
1!
n!
Dieses Polynom approximiert die Funktion f(x) in der Umgebung von x = a.
Drei verschiedene Differenzenverfahren ergeben sich durch Umformungen aus der
Taylor-Formel, um partielle Ableitungen erster Ordnung zu diskretisieren.
Die kontinuierlichen Variablen x, y und z werden zu diskreten Variablen i, j und k
transformiert.
 ∂y 
 
 ∂h  i , j
 y i +1, j − y i , j
+ O(∆h)

∆
h

 y i , j − y i −1, j
+ O(∆h)
=
∆h

 y i +1, j − y i −1, j + O(∆h)

2∆h

Hier sind die finiten Differenzen entlang der i-Achse dargestellt. Völlig analog gelten
sie auch für die j-Achse.
Die erste Variante ist eine so genannte Vorwärtsdifferenz. Die aktuelle Position wird
vom rechten Nachbarpunkt subtrahiert und durch den Gitterpunktabstand h dividiert,
weil man sich eine Einheit auf dem Gitter bewegt. Den Fehlerterm O(∆h) kann man
vernachlässigen. Analog verhält sich die Rückwärtsdifferenz.
Zur Diskretisierung der Wellengleichung werden Zentraldifferenzen verwendet, die
hier als dritte Möglichkeit aufgeführt sind. Die Zentraldifferenz subtrahiert den „linken“
Punkt vom „Rechten“ und dividiert anschließend durch den doppelten Gitterpunktabstand h, weil hier die zweifache Distanz beschritten wird.
Für die Wellengleichung benötigt man die finiten Differenzen für die zweiten partiellen Ableitungen. Aus der Taylor-Formel ergibt sich folgender Term für die Zentraldifferenz:
y
− 2 y i , j + y i −1, j
 ∂2 y 
 2  = i +1, j
+ O(∆h) 2
2
(∆h )
 ∂h  i , j
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 12 von 99
2
∂2 y
∂2 y 
2 ∂ y
Eingesetzt in die Wellengleichung
= c  2 + 2  ergibt sich:
∂t 2
∂z 
 ∂x
y it,+j1 − 2 y it, j + y it,−j1
(∆t )2
 y it+1, j − 2 y it, j + y it−1, j y it, j +1 − 2 y it, j + y it, j −1 

=c 
+
2
2


(
)
(
)
x
z
∆
∆


2
Unter der Annahme eines regulären Gitters mit konstantem Gitterabstand h über beide Achsen ergibt sich mit ∆x = ∆z = h :
y it,+j1 − 2 y it, j + y it,−j1
(∆t )2
 y it+1, j − 2 y it, j + y it−1, j y it, j +1 − 2 y it, j + y it, j −1 

=c 
+
2
2


(
)
(
)
h
h
∆
∆


2
y it,+j1 − 2 y it, j + yit,−j1 =
c 2 (∆t )
(∆h )
2
2
(y
t
i +1, j
+ y it−1, j + y it, j +1 + y it, j −1 − 4 y it, j
)
Gesucht ist die Lösung von y it,+j1 , dem Höhenwert der Membran an einem diskreten
Punkt i,j zum Zeitpunkt t+1:
y
t +1
i, j
=
c 2 (∆t )
(∆h )
2
2
(y
t
i +1, j
+y
t
i −1, j
+y
t
i , j +1
+y
t
i , j −1
)
2

c 2 (∆t )
+  2 − 4
(∆h )2

 t
 y i , j − y it,−j1


Aus dieser Diskretisierung wird ersichtlich, dass hier nur die unmittelbaren Nachbarpunkte Einfluss auf die neue Höhe eines Punktes haben und keine weiter entfernten
Punkte.
Abbildung 4: Einfluss der Nachbarpunkte in der diskreten Wellengleichung
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 13 von 99
Aus dem Zeitschritt t werden die umliegenden Nachbarn aufaddiert und je nach Wahl
der Konstanten c, ∆t und ∆h die Höhe des Punktes selbst subtrahiert. Im letzten
Term wird die Höhe des Punktes schließlich aus dem vorherigen Zeitschritt subtrahiert. Weitere Informationen finden sich in [2].
Eine Shader-basierte Implementierung ist jetzt kein Problem mehr, da nur auf Nachbarpunkte zugegriffen werden muss und sich die arithmetischen Funktionen auf Addition, Subtraktionen und Multiplikationen beschränken. Diese Funktionalität stellen
Pixel-Shader zur Verfügung.
2.1.3. Diskretisierung der Membran
Wie oben schon angedeutet kann die Membran durch ein reguläres Gitter modelliert
werden, das sich als Array oder Textur abspeichern lässt. Zwischen den einzelnen
Gitterpunkten ist der Abstand h konstant für beide Achsen, x und z. Man kann diesen
Abstand h als 1 annehmen und somit die Diskretisierung nochmals vereinfachen.
Genauso kann man die Zeit ∆t auf 1 setzen.
Jedem Gitterpunkt ist eine Höhe y zugeordnet, die die Auslenkung der Membran bestimmt. Insgesamt ist das Gitter N x N Punkte groß, wobei das Gitter nicht zwingend
quadratisch sein muss.
Zur Initialisierung werden alle Höhenwerte der Membran auf 0 gesetzt, womit die
Wasseroberfläche als ruhig angenommen wird und sich in beide Richtungen, nach
oben und unten bzw. in positiver und negativer y-Richtung, auslenken kann.
Abbildung 5: Diskretes Gitter zur Modellierung der Membran
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 14 von 99
2.1.4. Numerische Stabilität
So einfach das oben beschriebene Verfahren auch ist, es hat einen entscheidenden
Nachteil: es ist numerisch instabil. Numerische Instabilität bedeutet, dass sich bei der
Durchführung der Berechnungen Fehler aufsummieren, und sich somit im Laufe der
Zeit Überschwinger zu nicht mehr endenden Oszillationen aufschaukeln. Wenn es so
weit kommt, sind die Ergebnisse nicht mehr brauchbar.
Das oben beschriebene Verfahren ist ein explizites Verfahren. Bei einem expliziten
Verfahren liegen alle Eingabewerte bereits vor. In diesem Fall sind das die Höhenwerte aus dem letzten bzw. vorletzten Zeitschritt. Es gibt nur eine Gleichung und eine
Unbekannte, nämlich den neuen Höhenwert.
Die Lösung lässt sich sehr schnell und einfach explizit durch Auswerten der Formel
berechnen, aber darin liegt eine Fehlerquelle. Nur für einen sehr eingeschränkten
Parameterbereich von c, ∆t und ∆h liefert das Verfahren vernünftige Ergebnisse.
Zur numerisch stabilen Lösung der Wellengleichung ist ein implizites Verfahren notwendig. Um aus der expliziten Formel eine Implizite zu machen, wird nach dem
Crank-Nicholson-Verfahren der Höhenwert zum Zeitpunkt t mit dem Höhenwert zum
Zeitpunkt t+1 gemittelt.
y
t
i, j
(y
=
t +1
i, j
+ yit, j
)
2
Weitere Erläuterungen zum Crank-Nicholson-Verfahren finden sich in [10], [11], [12]
und [13].
Eingesetzt in die explizite Formel ergibt sich:
yit,+j1 − 2 yit, j + yit,−j1
(∆t )2
(
) (
) (
) (
) (
 yit++11, j + yit+1, j + yit−+11, j + yit−1, j + yit,+j1+1 + yit, j +1 + yit,+j1−1 + yit, j −1 − 4 yit,+j1 + yit, j
=c 
2

2(∆h )

2
) 


Um diese Gleichung nach yit,+j1 lösen, braucht man die umliegenden Werte von y zum
Zeitpunkt t+1. Mit Hilfe eines Gleichungssystems kann man diese Formel berechnen.
Das Lösen von Gleichungssystemen geht über den Rahmen dieser Diplomarbeit
hinaus und wird nicht weiter betrachtet. In [7] wird ein implizites Lösungsverfahren
vorgestellt.
Damit das explizite Verfahren vernünftige Ergebnisse liefert, müssen die Konstanten
c, ∆t und ∆h sorgfältig gewählt werden und folgende Stabilitätsbedingung erfüllen.
1
c 2 (∆t )
≤
2
2
(∆h )
2
Weitere Informationen zur Stabilitätsbedingung finden sich in [2].
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 15 von 99
Wenn man diese Bedingung beachtet, liefert das explizite Verfahren brauchbare
Werte. Allerdings kommen die Wellen, sobald sie einmal in Gang gebracht wurden,
nie wieder zur Ruhe. Deshalb ist eine zusätzliche Dämpfung notwendig.
2.1.5. Dämpfung
Um permanente Wellen zu vermeiden, die sich aus dem expliziten Verfahren ergeben, bedarf es einer Dämpfung der Wellengleichung. Positiver Nebeneffekt der
Dämpfung ist, dass man damit auch Ufer, an denen die Wellenbewegung abflacht,
oder Inseln im See simulieren kann.
Der einfachste Ansatz ist die Einführung einer Dämpfungskonstante d, die den gesamten Term abdämpft.
y
t +1
i, j
2
 c 2 (∆t )2 t

c 2 (∆t )
t
t
t


y i +1, j + y i −1, j + y i , j +1 + y i , j −1 +  2 − 4
=d
 (∆h )2
(∆h )2


(
)

 t
 y i , j − y it,−j1 




Der Wertebereich für d liegt zwischen 0 und 1. In der Praxis haben sich bereits
Dämpfungskoeffizienten von 0.95 als ausreichend erwiesen um permanente Wellen
zu vermeiden.
Für Ufer oder Inseln kann man den Dämpfungskoeffizienten ortsabhängig machen:
di,j. In der Implementierung wurde eine zweidimensionale Exponentialfunktion bzw.
Gauss-Glocke als Dämpfung verwendet.
2
2
d i , j = e − r ⋅((i −0.5 ) + ( j −0.5 ) )
Den Radius der Funktion bestimmt der Parameter r. Die Verschiebung von i und j um
0.5 legt das Zentrum der Auswölbung in die Mitte des Feldes mit i, j ∈ [0;1] .
Durch diese Dämpfungsfunktion werden die Wellen zum Rand abgebremst, so dass
ein Ufer simuliert werden kann.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 16 von 99
Abbildung 6: Dämpfungsfunktion in der Wasserdemo
2.1.6. Einschläge von Objekten auf die Wasseroberfläche
Bis jetzt ist die Membran noch in ihrer Ausgangslage, der x-z-Ebene. Damit sich Wellen bilden können, muss zuerst ein Einschlag auf die Membran erfolgen, der sie auslenkt. Je nach Form des Objekts, das ins Wasser fällt, wird ein bestimmtes Volumen
an Wasser mit der Form des Objekts verdrängt.
Der einfache Versuch nur einzelne Punkte der Membran auszulenken scheitert an
der hohen Unstetigkeit mit den umliegenden Punkten. Durch die explizite Lösung der
Wellengleichung breiten sich die Unstetigkeiten über die Membran aus und der Realismus der Simulation geht verloren. Mit einem impliziten Verfahren treten solche
Probleme nicht auf.
Im Folgenden werden nur Einschläge von Regentropfen bzw. relativ runden Objekten
untersucht, da sich die Einschläge runder Objekte wieder gut mit einer zweidimensionalen Exponentialfunktion beschreiben lassen.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 17 von 99
Um unterschiedlich große Objekte zu simulieren, wie zum Beispiel Regentropfen
oder größere, runde Steine, kommt diesmal neben dem Einschlagsradius auch noch
die Einschlagstiefe a ins Spiel.
2
2
d i , j = a ⋅ e −r⋅((i −0.5 ) +( j −0.5 ) )
Zusammen mit dem Einschlagsradius r bestimmt die Einschlagstiefe a die Charakteristik des Einschlags. Kleiner Radius mit hoher Tiefe simuliert zum Beispiel kleine,
schwere Metallkugeln, die mit großer Kraft ins Wasser geworfen werden. Regentropfen haben einen kleinen Einschlagsradius mit geringer Einschlagstiefe. Einen großen
Radius und geringe Tiefe verursachen Schlauchboote, die ins Wasser gelassen werden.
Die Parameter i und j bestimmen, wie gehabt, die Einschlagsstelle auf der Membran.
Je nach Zusammenspiel der Parameter entstehen durch Berechnung der Wellengleichung auch unterschiedliche Ausbreitungsformen der Wellen. Bei geringer Einschlagstiefe entsteht meist nur eine einzelne Welle, die sich über die Membran ausbreitet. Bei anderen Parameterkombinationen können sehr viele und große Wellen
entstehen.
Abbildung 7: Regentropfeneinschläge und Wellenausbreitung
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Abbildung 8: Große Einschläge und Wellenausbreitung
Seite 18 von 99
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 19 von 99
2.2. Modellierung des Lichts
Nachdem die geometrische Wellenausbreitung berechnet ist, geht es nun darum, die
optische Darstellung zu verbessern. Dazu werden verschiedene Aspekte des Lichts
nachmodelliert.
Als erstes werden die Lichtfarbe und -intensität nach dem Phong-Illumination-Model
berechnet. Je nach Position der Lichtquelle werden damit bestimmte Wellenkämme
und -täler beleuchtet. Das Lichtmodell ist zwar sehr einfach, sorgt aber für eine täuschend echte Beleuchtung der Szene.
Im zweiten Schritt werden Lichtreflexionen berechnet. Lichtstrahlen, die aus der Umgebung kommen, werden an der Wasseroberfläche reflektiert und treffen im Auge
des Betrachters ein. Die Reflexion sorgt für eine große Verbesserung der optischen
Qualität.
Als letztes wird die Lichtbrechung berechnet. Lichtstrahlen, die auf die Wasseroberfläche auftreffen, werden teilweise reflektiert und teilweise gebrochen. Unter Lichtbrechung versteht man die Ablenkung der Lichtrichtung an der Oberfläche zu einem
Medium mit unterschiedlicher optischer Dichte.
Alle drei Lichtaspekte erfordern die Oberflächennormalen des Wassers in jeder diskreten Gitterzelle. Dies wird zuerst untersucht.
2.2.1. Berechnung der Normalen der Wasseroberfläche
Gegeben ist das reguläre, diskrete Gitter mit den aktuellen Höhenwerten der Auslenkung. Die Frage ist, wie man aus den Höhenwerten Oberflächennormalen berechnen
kann.
Wie aus den obigen Bildern ersichtlich, wird das Gitter stets in Form von Dreiecken
dargestellt. Zwei Dreiecke bilden ein Quadrat, dessen Ecken Höhenwerte aus den
Wellenberechnungen zugeordnet sind.
Die Berechnung der Normalen eines Dreiecks ergibt sich direkt aus dem Vektorprodukt der Dreiecksschenkel v1 und v2.
n f = v1 × v 2
Anschließend muss man die Normale normalisieren, so dass ihre Länge 1 wird.
Mit den Dreiecksnormalen kann man zunächst nicht viel anfangen, da man die Normalen auf einem Höhenpunkt benötigt. Sie wird Vertexnormale oder Vektornormale
genannt. Da an jedem Höhenpunkt mehrere Dreiecke anliegen, kann man deren
Dreiecksnormalen zusammenaddieren und mit ihrem Winkel in diesem Punkt gewichten.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 20 von 99
Abbildung 9: Berechnung einer Dreiecksnormalen
Dieses Verfahren ist zu aufwändig für Echtzeitanwendungen, weil die Normalen
durch Wellenbewegung für jedes Bild und für jeden Punkt neu berechnet werden
müssen. Man braucht eine einfachere Methode.
Zur Vereinfachung der Berechnung wird angenommen, dass jeder Punkt v genau zu
vier umliegenden Dreiecken gehört. Von v gehen vier Vektoren v1...4 zu den direkten
Nachbarpunkten.
Abbildung 10: Nachbarschaftsbeziehung
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 21 von 99
Zur Erinnerung: das Gitter erstreckt sich in x-z-Ebene und der y-Wert entspricht der
Höhe.
Als zweite Annäherung an die Normale, geht man davon aus, dass alle vier Dreiecksnormalen den gleichen Anteil zur Normale von v beitragen. Falsch wird die Annahme, sobald die Höhenwerte weit auseinander liegen, weil dann die Winkel um v
nicht mehr in der Nähe von 90° sind. Um eine möglichst einfache und schnell berechenbare Formel zu erhalten, wird dieser Fehler in Kauf genommen.
Mit den obigen Vereinfachungen berechnet man die Normale von v aus dem Mittelwert der umliegenden Dreiecksnormalen.
nv =
(n1 + n2 + n3 + n 4 )
4
Die Dreiecksnormalen n1...4 werden wie oben beschrieben aus dem Vektorprodukt
ihrer beiden Dreiecksschenkel berechnet. Als weitere Vereinfachung kann man den
Gitterabstand h als 1 annehmen, wodurch die x- und z-Komponenten der Vektoren
v1…4 zu Werten aus {-1; 0; 1} werden.
 1 


v1 =  y1 − y 0 ;
 0 


 0 


v 2 =  y 2 − y 0 ;
 1 


 −1 


v3 =  y 3 − y 0 ;
 0 


 0 


v 4 =  y 4 − y 0 ;
 −1 


Eingesetzt in die Kreuzprodukte ergibt das:
 − y1 + y0 


1
n1 = v1 × v2 = 
;
− y + y 
0
 2
 y3 − y 0 


n 3 = v3 × v4 =  1 ;
y −y 
0
 4
In nv =
 y3 − y0 


1
n 2 = v 2 × v3 = 
;
− y + y 
0
 2
 − y1 + y 0 


1
n4 = v4 × v1 = 
;
 y −y 
0 
 4
(n1 + n2 + n3 + n 4 )
eingesetzt ergibt sich für die Normale in v:
4
 − y1 + y 0 + y 3 − y 0 + y 3 − y 0 − y1 + y 0 
 2( y 3 − y1 ) 
 1

1
4
nv = 
4
= 

4
4


 − y2 + y0 − y2 + y0 + y4 − y0 + y 4 − y0 
 2( y 4 − y 2 ) 
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 22 von 99
Da die Länge der Normalen sowieso noch normalisiert werden muss, kann man auf
die Koeffizienten verzichten und man kommt auf diese einfache Formel zur Berechnung der Normalen, die nur auf benachbarte Höhenwerte zugreift:
 y 3 − y1 


nv =  2 
y − y 
2
 4
Ausführlichere Darstellungen zur Berechnung der Vertexnormalen in Höhenfeldern
sind in [2] ausgeführt.
2.2.2. Lichtfarbe und Lichtintensität (Phong-Illumination-Model)
Da nun die Normalen der Oberfläche bekannt sind, kann man berechnen, wie viel
Licht von einer Quelle auf einen Oberflächenpunkt trifft. Das Phong-IlluminationModel vereinfacht den komplexen Strahlenverlauf des Lichts auf eine elementare
Formel.
Auf eine Oberfläche mit der Oberflächennormale N trifft unter einem bestimmten
Winkel α ein Lichtstrahl L. Je nach den Eigenschaften der Oberfläche wird dieser
Lichtstrahl unter dem gleichen Ausfallswinkel an der Oberfläche reflektiert. Oftmals
wird anstatt des Reflexionsvektors R der so genannten Halbvektor H als Näherung
verwendet. Der Betrachtungsvektor V bestimmt den Winkel unter dem der Betrachter
auf die Oberfläche blickt.
Abbildung 11: Phong-Illumination-Model
Drei Komponenten hat dem Phong-Modell zufolge das Licht, das in [16] erstmals
vorgestellt wurde: das Umgebungslicht, diffuse Lichtreflexion und spekulare Reflexion.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 23 von 99
Ambient
Das Umgebungslicht einer Szene wird durch einen konstanten Ambient-Anteil im
Licht modelliert. Anstatt den komplexen Strahlenverlauf des Lichts zu berechnen, der
sich nur durch eine globale Beleuchtung modellieren lässt, wird pro Oberfläche eine
Farbe CAmbient(Rot, Grün, Blau) definiert, die sie emittieren soll. Mittels des Koeffizienten KAmbient, der zwischen 0 und 1 liegt, wird die Intensität der Farbe gewichtet.
Ambient = K Ambient ⋅ C Ambient (R, G , B )
Sowohl die Farbe als auch der Koeffizient des Umgebungslichts sind Eigenschaften
des Oberflächenmaterials und können pro Oberfläche unterschiedlich definiert werden. Die Bestimmung der Farbe und des Koeffizienten unterliegen keinen physikalischen Gesetzen. Sie werden meist empirisch festgelegt.
Diffuse Reflexion
Die diffuse Reflexion des Lichts beschreibt die Lichtintensität in Abhängigkeit von der
Richtung des Lichteinfalls und der Oberfläche. Die Lichtintensität hängt vom Winkel α
zwischen dem Lichtvektor L und der Oberflächennormale N ab.
Bei einem Winkel von 0° wird das Licht maximal reflektiert und es entsteht die größte
Lichtreflexion. Je größer der Winkel wird, desto weniger Licht wird reflektiert. Wenn
der Winkel größer als 90° ist, dann liegt Lichtquelle hinter der Oberfläche, und sie
wird gar nicht von beleuchtet.
Die Lichtfarbe CDiffuse(Rot, Grün, Blau) sowie der Koeffizient KDiffuse sind wieder Materialkonstanten.
Diffuse = K Diffuse ⋅ C Diffuse (R, G, B ) ⋅ cos(α )
Wenn die beiden Vektoren L und N normalisiert sind, so kann der Cosinus durch ein
Skalarprodukt ausgerechnet werden.
Wenn mehrere Lichtquellen modelliert werden sollen, dann wird die Beleuchtung wesentlich realistischer, wenn man noch den Abstand der Lichtquellen von der Oberfläche hinzunimmt. Dies erfolgt durch einen weiteren Koeffizienten im Term, der nach
den physikalischen Gesetzen mit dem quadrierten Inversen des Abstandes eingeht.
Spekulare Reflexion (Glanzlichter)
Während das Umgebungslicht und der diffuse Lichtanteil unabhängig von der Position des Betrachters sind, entstehen Glanzlichter, wenn der Betrachter in die Reflexion
des Lichts an der Oberfläche blickt. Je kleiner der Winkel zwischen Betrachtervektor
und Reflexionsvektor des Lichts ist, desto größer sind der reflektierte Lichtanteil und
damit das Glanzlicht.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 24 von 99
Nach Phong ist der Übergang nicht linear. Stattdessen wird die Intensitätsabnahme
durch cos n ( β ) bestimmt, wobei β ist der Winkel zwischen Betrachtungsvektor V und
Reflexionsvektor R ist. Der Parameter n ist eine materialspezifische Konstante ist.
1,2000
1,0000
0,8000
cos β
cos2 β
cos64 β
0,6000
0,4000
0,2000
1,5463
1,4358
1,3254
1,2149
1,1045
0,9940
0,8836
0,7731
0,6627
0,5522
0,4418
0,3313
0,2209
0,1104
0,0000
0,0000
Abbildung 12: Materialspezifische Konstante n
Für n = 1 ergibt sich eine weiche Intensitätsabnahme, während bei großen n scharfe
Glanzlichter ergeben.
Wie schon beim diffusen Lichtanteil kann der Winkel β durch ein Skalarprodukt von V
und R berechnet werden, wenn beide Vektoren normalisiert sind.
Die Farbe des Glanzlichtes einer Oberfläche wird durch CSpecular(Rot, Grün, Blau)
festgelegt und ihre Intensität durch KSpecular.
Specular = K Sepcular ⋅ C Specular (R, G, B ) ⋅ cos n (β )
Alle drei Terme zusammengenommen ergeben das Phong-Illumination-Model.
C Phong = K Ambient ⋅ C Ambient + K Diffuse ⋅ C Diffuse ⋅ cos(α ) + K Sepcular ⋅ C Specular ⋅ cos n (β )
CPhong bestimmt die Lichtfarbe und die Lichtintensität am gesuchten Oberflächenpunkt.
Eine detaillierte Beschreibung und andere, komplexere Lichtmodelle kann in [4]
nachgelesen werden.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 25 von 99
2.2.3. Lichtreflexion
Sowohl im Phong-Illumination-Model als auch bei der Berechung von Spiegelungen
der Umgebung im Wasser wird der Reflexionsvektor R eines eintreffenden Strahles
V an einer Oberfläche mit der Normale N benötigt.
Abbildung 14: Reflexionsvektor
Um den Reflexionsvektor R zu bestimmen müssen der Betrachtungsvektor V und die
Oberflächennormale N normalisiert sein.
Wie in [4] beschrieben, kann man den Reflexionsvektor durch geometrische Überlegungen herleiten: Die Projektion von V auf N ist N · cos α. Im linken Dreieck ist
N · cos α = V + S. Um vom Ursprung zu R zu gelangen folgt man erst dem Vektor V
und dann den beiden Vektoren S, die aus Symmetriegründen gleich sein müssen.
R =V + 2⋅S
Setzt man S = N ⋅ cos α − V in R ein ergibt sich:
R = V + 2 ⋅ ( N ⋅ cosα − V )
R = V + 2 ⋅ N ⋅ cosα − 2 ⋅ V
R = 2 ⋅ N ⋅ cosα − V
Den Winkel α kann man durch ein Skalarprodukt ausdrücken, wenn die Vektoren
normalisiert sind und es ergibt sich schließlich folgende Formel für den Reflexionsvektor.
R = 2 ⋅ (V • N ) ⋅ N − V
Im Blinn-Phong-Illumination-Model (siehe [17]) wird auf die explizite Berechnung des
Reflexionsvektors verzichtet um die Berechnung möglichst schnell zu machen. Für
den spekularen Lichtanteil wird der Winkel zwischen dem Betrachtervektor V und
dem Reflexionsvektor des Lichts R benötigt. Anstatt R wird der so genannte Halbvektor H verwendet, der zwar nur eine grobe Näherung an den Reflexionsvektor ist, aber
dafür sehr schnell berechenbar ist:
L +V
H=
L +V
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 26 von 99
Abbildung 13: Regentropfeneinschläge von oben mit Phong-Beleuchtung
Cube Mapping
Um Spiegelungen der umgebenden Landschaft auf der Wasseroberfläche zu berechnen, wird der Reflexionsvektor R als Index in eine so genannte Cube Map verwendet werden.
Cube-Maps bestehen aus sechs Texturen, die an die Innenseiten eines Würfels angebracht sind. Sie werden dazu benutzt, die umgebende Landschaft um einen Betrachtungspunkt darzustellen, der genau in der Mitte des Würfels liegt. Jede Seitenfläche enthält eine Bild der Szene mit einem Sichtwinkel von 90° in horizontaler und
vertikaler Achse. Wenn man alle sechs Seitenflächen auf die Innenseiten eines Würfels setzt, ergibt sich ein kontinuierliches 360° Panoramabild über alle Achsen um
den Szenenmittelpunkt.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 27 von 99
Abbildung 15: Sechs Seiten einer Cube-Map
Um Reflexionen aus der umgebenden Szene zu simulieren, wird der Reflexionsvektor als Index in die Cube Map verwendet. Dazu wird in Richtung der längsten der drei
Vektorkomponenten U, V, W eine der sechs Seitenflächen ausgewählt und mit den
anderen beiden innerhalb dieser Textur ein konkretes Pixel adressiert.
Sei W ist längste Komponente, dann werden die zweidimensionalen Texturkoordinaten U’ und V’ in eine der Seitentexturen mit einer Projektion berechnet:
U ' = U /W
V ' = V /W
Auf diese Weise erhält man Spiegelungen der umgebenden Landschaft auf der
Wasseroberfläche. Ausführlichere Beschreibungen finden sich in [3], [4], [15] und
[18].
Abbildung 16: Reflexion der Umgebung im Wasser
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 28 von 99
2.2.4. Lichtbrechung
Ein Teil des Lichts, der auf eine Wasseroberfläche trifft, wird reflektiert, ein anderer
Teil gelangt unter die Wasseroberfläche. Beim Medienwechsel zwischen Luft und
Wasser kommt es zur Lichtbrechung. Der Lichtstrahl wird von seiner ursprünglichen
Richtung an der Wasseroberfläche abgelenkt.
In der nachfolgenden Abbildung wird die Berechnung des Brechungsvektors,
manchmal auch Refraktionsvektor genannt, aufgezeigt.
Abbildung 17: Brechungsvektor
Das Verhältnis zwischen dem Eintreffwinkel des Lichts α auf der Wasseroberfläche
und β, dem Brechungswinkel unter Wasser, wird Brechungsindex ηr genannt.
ηr =
sin β
sin α
Gegeben sind der einfallende Lichtvektor L, die Oberflächennormale N in einem
Punkt und der Brechungsindex ηr.
Aus geometrischen Überlegungen ergibt sich der Brechungsvektor zu:
B = sin β ⋅ M − cos β ⋅ N
Der Einheitsvektor M steht senkrecht auf der Oberflächennormalen N und liegt in der
Ebene, die N und L aufspannen. Wie aus obiger Abbildung ersichtlich, zeigt S in die
gleiche Richtung wie M. Um M zu berechnen muss S mit sin α skaliert werden.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
M =
Seite 29 von 99
N ⋅ cos α − L
sin α
Eingesetzt in B = sin β ⋅ M − cos β ⋅ N ergibt sich:
B=
Mit η r =
sin β
⋅ (N ⋅ cosα − L ) − cos β ⋅ N
sin α
sin β
ergibt sich für B:
sin α
B = (η r ⋅ cos α − cos β ) ⋅ N − η r L
Durch das Skalarprodukt (N · L) kann cos α bestimmt werden, cos β kann über
Phythagoras berechnet werden:
cos β = 1 − sin 2 β
Die Quadrierung von η r =
sin β
ergibt nach sin2 β aufgelöst:
sin α
sin 2 β = η r ⋅ sin 2 α
2
Eingesetzt in die Formel für cos β und zugleich sin2 α durch Phythagoras ersetzt erhält man:
(
cos β = 1 − sin 2 β = 1 − η r2 sin 2 α = 1 − η r2 1 − ( N ⋅ L )
2
)
Der Brechungsvektor B = (η r ⋅ cosα − cos β ) ⋅ N − η r L ist somit:
(
)
2
B = η r ⋅ ( N ⋅ L ) − 1 − η r2 1 − ( N ⋅ L )  ⋅ N − η r L


In der nachfolgenden Tabelle sind einige Brechungsindizes ηr für verschiedene Medien aufgeführt.
Medium
Diamant
Schwefelkohlenstoff
Kanadabalsam
Benzol
Quarzglas
Wasser
Brechungsindex ηr
2,4173
1,6277
1,5420
1,5014
1,4584
1,3330
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 30 von 99
In dieser Implementierung wurde die Länge des Refraktionsvektors nicht weiter verwendet. In Abhängigkeit von der Länge können Intensitätsabnahmen oder Farbfrequenzverschiebungen modelliert werden.
Mit Hilfe der Lichtbrechung gelingen die typischen Verzerrungen, die man beobachten kann, wenn durch klares Wasser auf den Grund blickt. Wenn man im Hallenbad
in ein tiefes Becken schaut und das Wasser ruhig ist, sieht das Becken meist nicht so
tief aus wie es eigentlich ist. Dieser Effekt beruht auf der Lichtbrechung.
Weitere Ausführungen zur Lichtbrechung findet man in [4] und [19].
Abbildung 18: Lichtbrechung
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 31 von 99
2.3. Implementierung
2.3.1. Lösung der Wellengleichung in Grafikhardware
Wie schon weiter oben angedeutet, werden bei der Implementierung nur PixelShader Programme verwendet. Die Berechnung der Höhenwerte erfolgt in Arrays
bzw. Texturen auf Pixel- bzw. Fragment-Basis und nicht in Vektoren, die in VertexShader Programmen verarbeitet werden.
Zum Berechnen der Wellengleichung in Grafikhardware werden zwei Texturen benötigt, die die Höheninformation für die Zeitpunkte t+1, t und t-1 speichern. Zwei Texturen sind deshalb ausreichend, weil man als Eingabe für die Wellengleichung die
Texturen zu den Zeitpunkten t und t-1 benötigt und das Ergebnis für den Zeitschritt
t+1 in der Textur t-1 ersetzten kann. Es werden keine umliegenden Punkte aus t-1
benötigt.
Des Weiteren ist eine Dämpfungstextur d notwendig, die die Dämpfungskoeffizienten
pro Punkt speichert.
Abbildung 19: Texturen und Funktionsweise des Wellen-Pixel-Shaders
Die Arbeitsweise läuft nach diesem Schema ab: Die Wellentexturen t und t-1 sowie
die Dämpfungstextur d wird als Parameter an den Wellen-Shader übergeben, genauso wie die Konstanten c, ∆t und ∆h. Mit der diskretisierten Form der Wellengleichung errechnet der Shader Punkt für Punkt die neuen Höhenwerte zum Zeitpunkt
t+1 aus. Die Ergebnisse speichert er in der Textur t-1.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 32 von 99
Sobald ein Shader-Pass abgeschlossen ist, werden die Labels der Wellentexturen
geändert: Die soeben berechnete Textur t-1 als Textur t, und die ehemalige Textur t
als Textur t-1 deklariert. So ist kein Umkopieren von Texturen notwendig.
Um die gesamte Textur beim Rendern zu erreichen, wird ein Quadrat über die Fläche in einem Vertex-Buffer aufgespannt. Damit jeder Pixel der Texturen genau einmal bearbeitet wird, werden die Welt- und Kameramatrix auf die Einheitsmatrix und
die Projektionsmatrix wird auf eine orthogonale Projektion gesetzt. So wird auf zweidimensionaler Pixelebene gearbeitet.
Einige Worte zum Texturformat: Die drei Texturen benötigen jeweils nur eine Komponente. Wenn man das Programm auf minimalen Video-Speicherplatz optimieren
will, kann man die Texturen t, t ± 1 und d in eine Textur mit vier Komponenten speichern, wobei eine frei bleibt. Die Shader werden dadurch aber komplizierter.
Neben der Anzahl der Komponenten ist noch die Frage nach dem Datentyp von Bedeutung. Es bieten sich 32-bit-float-Texturen an, da man hier uneingeschränkt positive und negative Fließkommazahlen verwenden kann. Alternativ können auch 16bit-float-Texturen verwendet werden, mit denen man je nach GPU schneller, aber
auch ungenauer, rechnen kann.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 33 von 99
2.3.2. Zweidimensionale Darstellung
Als einfache Möglichkeit der Darstellung bietet sich die direkte Draufsicht auf die
Wassermembran an, wie es in Abbildung 18 dargestellt ist. Hierzu wird die aktuelle
Wellentextur t+1 in ein Rechteck auf dem Bildschirm hineingerendert. Als weitere
Eingabeparameter müssen für die Lichtreflexionen und Lichtbrechungen, auch Refraktionen genannt, die beiden entsprechenden Cube-Maps als Parameter mit übergeben werden. Das Demoprogramm Water2D demonstriert diese Vorgehensweise.
Abbildung 20: Funktionsweise des Licht-Pixel-Shaders
Die Demo Water2D wurde auf einem Rechner mit einer ATI Radeon 9700 Pro Grafikkarte geschrieben, weil das zur Entwicklungszeit die einzige Karte mit Unterstützung für den Pixel-Shader 2.0 Standard war. Zu den kompatiblen Karten zählen alle
ATI Radeon Modelle ab 9500.
Die sonstige Rechnerausstattung entspricht dem aktuellen Stand der Dinge. Der
Hauptprozessor ist ein AMD Athlon mit 1,2 GHz und der Hauptspeicher ist 512 MB
groß. Da das Programm unter DirectX 9.0 geschrieben wurde, wurde als Betriebssystem Windows XP Professional verwendet. Die Geschwindigkeit ist allerdings vom
verwendeten Rechensystem unabhängig, da es hier nur auf die Leistung der Grafikkarte ankommt.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 34 von 99
Im unten stehenden Diagramm wurden mit verschiedenen Gittergrößen und Bildschirmauflösungen Geschwindigkeitsmessungen durchgeführt. Die Messgröße ist
hierbei Bilder pro Sekunde bzw. Frames per Second im Englischen. In einem Bild
werden die gesamten Berechnungen der Wellengleichung und des Lichts inklusive
Reflexion und Refraktion durchgeführt.
Geschwindigkeitsmessungen
Bilder pro Sekunde
250
200
1024x768
800x600
640x480
150
100
50
0
64
128
256
512
Gittergöße
Abbildung 21: Geschwindigkeitsmessungen der Demo Water2D
Mit der Gittergröße ist die Seitenlänge des Quadrats gemeint. Um also die Anzahl
der Gitterpunkte zu erhalten, muss die Gittergröße quadriert werden.
Während die Framerate bei der höchsten Bildschirmauflösung zwischen dem größten und kleinsten Gitter nur um 15% sinkt, obwohl 64-mal mehr Gitterpunkte verarbeitet werden müssen zeigt, dass die Berechnung der Wellengleichung verhältnismäßig schnell von statten geht, dahingegen die Lichtberechnungen den größten Teil
der Rechenzeit ausmachen. Diese werden nämlich pro Punkt im Framebuffer ausgerechnet und sind daher sehr stark abhängig von der Bildschirmauflösung.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 35 von 99
2.3.3. Dreidimensionale Darstellung
Neben der zweidimensionalen Draufsicht auf das Wasser, stellt die dreidimensionale
Darstellung des Wassers eine interessante Erweiterung der bisherigen Überlegungen dar. Damit die Berechnungen weiterhin vollständig in Grafikhardware und ohne
Hauptprozessor durchgeführt werden können, müssen die Höhenwerte aus der Wellentextur an die Geometrieeinheit des Grafikprozessors weitergeleitet und in Punkte
umgesetzt werden.
Abbildung 22: Displacement Mapping
Dieses Verfahren nennt sich Displacement Mapping. Einem Gitter, das in x-y-Ebene
liegt, werden pro Vektor Texturkoordinaten mitgegeben an welcher Stelle eine
Displacement Map ausgelesen werden soll. In diesem Fall würde die jeweils aktuelle
Wellentextur als Displacement Map übergeben werden. Ein Vertex-ShaderProgramm greift pro Vektor darauf zu und verschiebt jeden Vektor um den jeweiligen
Höhenwert. Anschließend werden im Vertex-Shader das Phong-Illumination-Model,
Lichtreflexionen sowie Lichtbrechungen berechnet.
Das Demoprogramm Water3D verwendet Displacement Mapping nach dem DirectX
9.0 Standard. Auf einer Radeon 9700 Pro Karte – momentan die einzige Karte, die
Displacement Mapping unterstützt – erzielt man ca. 22 Bilder pro Sekunde, wenn
man eine Gittergröße von 64 mal 64 Zellen verwendet. Die Anzahl der Bilder pro Sekunde hängt hier nur von der Gittergröße ab, die Bildschirmauflösung spielt keine
Rolle.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 36 von 99
Bilder pro Sekunde
Geschwindigkeitsmessungen
80
70
60
50
40
30
20
10
0
32
64
128
256
Gittergröße
Abbildung 23: Geschwindigkeitsmessungen der Demo Water2D
Für kleine Gittergrößen liegt die Geschwindigkeit im akzeptablen Rahmen, während
größere Felder in Echtzeitanwendungen nicht zu gebrauchen sind. Die Hardwareunterstützung wird sich wahrscheinlich in den nächsten Generationen der Grafikkarten
verbessern.
Abbildung 24: Water3D mit 64² Gitterzellen, Phong-Beleuchtung und Lichtreflexion
Im Vertex-Shader 3.0 Standard, den noch keine Grafikkarte unterstützt, wird es eine
Technik namens Vertex-Texturing geben, womit in Vertex-Shader-Programmen Texturzugriffe erlaubt werden. Dies ist eine weitere Variante eine dreidimensionale Darstellung zu implementieren, die vollständig in Grafikhardware abläuft.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 37 von 99
3. Simulation von Fluiden
Was versteht man eigentlich unter einem Fluid? Ein Fluid ist flüssige oder gasförmige
Materie, die sich entlang von Strömungen sowie durch Diffusion ausbreitet und verwirbelt. Wenn man beispielsweise etwas Milch in den Kaffee gibt und kurz umrührt,
kann man beobachten, wie die Milch im Kaffee wolkenähnliche Gebilde formt. Wissenschaftliche Anwendungen der Berechnung von Fluiden kommen vor allem aus
dem Bereich des Bauingenieurwesens und des Maschinenbaus. So werden zum
Beispiel beim Bau von Staudämmen Wasserverwirbelungen berechnet, denen der
Damm Stand halten muss. Beim Brückenbau ist es wichtig Luftverwirbelungen zu
kalkulieren, um sicher zu gehen, dass die Brücke nicht durch Turbulenzen einstürzt.
Im Maschinenbauwesen spielen Fluide beispielsweise im Fahrzeugbau eine Rolle. In
der Windkanalsimulation werden Luftströmungen berechnet, um das Fahrzeug möglichst windschnittig zu machen.
Die exakte mathematische und physikalische Beschreibung dieses Naturphänomens
liefern die so genannten Navier-Stokes-Gleichungen. Im vorherigen Teilprojekt ging
es um die Simulation einer Membran. Das Strömungsmodell dagegen kann auch dazu verwendet werden Strömungen in dreidimensionalen Volumen zu berechnen.
Wegen der begrenzten Rechenkapazität wird aber auch hier nur eine zweidimensionale Berechnung implementiert. Diese zweidimensionale Ebene kann man sich als
eine einzelne Schicht eines dreidimensionalen Volumens vorstellen.
Der Fokus liegt im folgenden Kapitel auf der Impuls- und der Kontinuitätsgleichung.
Weitere Navier-Stokes-Gleichungen werden im Kapitel Erweiterungen auf Seite 87
kurz angesprochen, aber nicht im Detail diskutiert oder implementiert.
3.1. Die inkompressiblen Navier-Stokes-Gleichungen
Das folgende Gleichungssystem beschreibt laminare, inkompressible, instationäre
Fluide. Laminare Fluide kann man sich als Strömungsschichten vorstellen, die sich
gegeneinander reiben und so Energie austauschen.
Abbildung 25: Laminare Strömungen
Im Gegensatz dazu haben turbulente Strömungen kaum Reibung, sondern die Teilchen können chaotisch die Schichten wechseln. Für diesen Fall kann das Reynoldsgleichungssystem verwendet werden.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 38 von 99
Inkompressible Fluide können – vereinfacht gesagt – nicht zusammengedrückt werden. Das gilt für Wasser, solange es nicht zum Kochen gebracht wird und in Dampf
übergeht. Luft ist andererseits ein kompressibles Medium, wie man beispielsweise an
der Erhitzung beim Aufpumpen eines Fahrradreifens beobachten kann.
Instationäre Probleme verändern mit der Zeit ihren Zustand. Im Kapitel Simulierte
Probleme ab Seite 79 werden sowohl stationäre Probleme wie die Nischenströmung
und auch instationäre Probleme wie die Wirbelstraße vorgestellt.
Die Navier-Stokes-Gleichungen werden hier in der dimensionslosen Darstellung verwendet. Für die Herleitung der dimensionslosen und dimensionsbehafteten NavierStokes-Gleichungen sei auf [6] verwiesen.
Dimensionslos bedeutet, dass alle Größen der Gleichung keine physikalischen Einheiten tragen. Eine Ausnahme ist nur die Reynoldszahl. Durch diese Darstellung
konnte man zeigen, dass sich Strömungen unabhängig ihres tatsächlichen Ausmaßes ähnlich verhalten. So erzeugt ein Tropfen Milch in einer Tasse Kaffee das gleiche Strömungsverhalten, wie ein runder Meteor, der in den Ozean fällt.
Impulsgleichung und Kontinuitätsgleichung
Die folgende Beschreibung wurde in starker Anlehnung an das Buch „Numerische
Simulation in der Strömungsmechanik“ [6] verfasst. In diesem Buch findet man noch
viele weitere Details, sowie weiterführende Thematiken.
Für Strömungen werden Richtungsvektoren benötigt, die besagen, in welche Richtung die Strömung an jeder Stelle fließt. Im zweidimensionalen Fall besteht ein Richtungsvektor aus zwei Komponenten u und v. Pro Richtungskomponente gibt es eine
partielle Differentialgleichung, die Impulsgleichung genannt wird:
( )
∂u ∂p 1  ∂ 2 u ∂ 2 u  ∂ u 2 ∂ (uv )

−
−
+ gx
+
=
+
∂y
∂t ∂x Re  ∂x 2 ∂y 2  ∂x
( )
∂v ∂p 1  ∂ 2 v ∂ 2 v  ∂ (uv ) ∂ v 2

−
−
+ gy
+
=
+
∂x
∂y
∂t ∂y Re  ∂x 2 ∂y 2 
Zur Massenerhaltung wurde die so genannte Kontinuitätsgleichung hergeleitet, die
die Divergenzfreiheit garantiert:
∂u ∂v
+
=0
∂x ∂y
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 39 von 99
Die beiden Gleichungen werden auf einem rechteckigen, zunächst kontinuierlichem,
Gebiet Ω := [0, a ]× [0, b] ⊂ R 2 gelöst. Dabei sind die gesuchten Größen in den Gleichungen:
u: die Geschwindigkeitskomponente des Fluids in x-Richtung
v: die Geschwindigkeitskomponente des Fluids in y-Richtung
p: der Druck
gx, gy: die äußeren Kräfte, die auf das Gebiet einwirken. Das können zum Beispiel Erdanziehungskräfte oder Corilis-Kräfte sein
t: die Zeit
Re: Nach dem englischen Physiker Reynolds benannt, beschreibt die Zähigkeit bzw. die Viskosität des Fluids. Je kleiner sie ist, desto zäher ist das Fluid.
Je größer sie ist, desto turbulenter ist das Fluid.
Zum besseren Verständnis der Gleichungen ein paar kurze Erläuterungen zu den
einzelnen Termen.
Anfangsbedingungen
Aus den obigen Differentialgleichungen ergibt sich ein Anfangswert-RandwertProblem. Zu Beginn der Simulation ist das Gebiet Ω mit Anfangswerten vorbelegt, die
die Kontinuitätsgleichung erfüllen. Die Geschwindkeitskomponenten u und v werden
mit u0 und v0 initialisiert, der Druck p mit p0.
Zeit
∂u
∂v
und
zum Tragen.
∂t
∂t
Unter diskreten Bedingungen lässt sich der Term folgendermaßen auffassen: aus
einem gegeben Zeitschritt werden die neuen Geschwindigkeitskomponenten u und v
zu einem späteren Zeitpunkt berechnet, die dann wiederum als Eingabe für den
nächsten Schritt fungieren können.
Der zeitliche Verlauf der Simulation kommt in den Termen
Divergenzfreiheit
∂u ∂v
+
= 0 wird gefordert, dass die Geschwindigkeitsvekto∂x ∂y
ren überall divergenzfrei sein müssen. Die Divergenzen müssen deswegen Null sein,
damit die Massenerhaltung gewährleistet ist. Divergenzfreiheit bedeutet, dass in einem Gebiet Ω genau soviel Masse hineinfließt wie herausfließt, damit die Masse im
Gebiet Ω immer gleich bleibt.
In Kontinuitätsgleichung
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 40 von 99
Druck
∂p
∂p
und
werden die Vektoren an Rändern und an Hindernissen
∂y
∂x
umso mehr abgelenkt, je senkrechter sie auf die Hindernisse treffen. Würde an Hindernissen kein Druck entstehen, würden in der Strömung mit geschwemmt werden.
Der Druck ist eine Gegenkraft gegen den Strom. Hinter Hindernissen können sich je
nach Viskosität des Fluids Wirbel bilden.
Durch den Druck
Diffusion
1  ∂ 2u ∂ 2u 
1  ∂ 2v ∂ 2v 
 2 + 2  und

 kommt der diffusive Anteil der
+
Re  ∂x 2 ∂y 2 
∂y 
Re  ∂x
Strömung zum Tragen.
Unter Diffusion versteht man den gleichmäßigen Energieaustausch benachbarter
Teilchen. Physikalisch entsteht die Diffusion durch Oberflächenkräfte, die zwischen
den einzelnen Fluidelementen wirken.
In den Termen
In diesem Fall bedeutet das, dass die Richtung und Länge jedes Geschwindigkeitsvektors von seinen Nachbarvektoren beeinflusst wird. Lässt man die Diffusion alleine
voranschreiten, ergibt sich im Laufe der Zeit ein homogenes Bild der Geschwindigkeitsvektoren. Die Diffusionsausbreitung ist unabhängig von der Richtung der Vektoren. Sie ist in alle Richtungen gleich groß, egal in welche Richtungen die Vektoren
zeigen, da sich nur benachbarte Fluidelemente reiben.
Konvektion (Advektion)
( )
( )
∂ u 2 ∂ (uv )
∂ (uv ) ∂ v 2
−
−
und −
, manchmal auch advektive
∂x
∂y
∂x
∂y
Terme genannt, beschreiben den Fluss im Geschwindigkeitsfeld. Mit Hilfe dieses
Terms werden Objekte entlang der Strömung bewegt. Dazu zählen nicht nur Partikel,
die im Strom mitgetragen werden, sondern auch die Geschwindigkeit selbst. Geschwindigkeit wird in sich selbst fort getragen.
Die konvektiven Terme −
Dieser Term beschreibt den eigentlichen Strom. Die physikalische Herleitung dieser
Terme erfolgt aus den Kräften, die zwischen den Massen der Fluidelemente wirken.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 41 von 99
Randbedingungen
An den Rändern des Gebiets Ω müssen Randbedingungen gewählt werden, da man
zwangsweise auf einem endlichen Gebiet rechnen muss. Es sind verschiedene Bedingungen denkbar, in dieser Simulation betrachten wir diese Vier:
Haftbedingung (no-slip): Die Geschwindigkeit ist am Rand Null. Anschaulich
haftet das Fluid am Rand.
Rutschbedingung (free-slip): Die Geschwindigkeit senkrecht zum Rand ist
Null, genauso wie die Normalableitung der Geschwindigkeit parallel zur Wand
Null ist.
Ausströmbedingung (outflow): Auf den Randbereich werden die unmittelbaren
Nachbarn im Fluid senkrecht zum Rand gesetzt. Dadurch ändert sich die Geschwindigkeit senkrecht zum Rand nicht.
Einströmbedingung (inflow): Die Geschwindigkeit wird am Rand fest vorgeben. Alle Einströmungen in dieser Simulation fließen vom linken Rand in das
Innere des Gebiets ein. Eine Variante der Einströmbedingung ist die Bandbedingung. Im Kapitel Simulierte Probleme ab Seite 79 wird darauf näher eingegangen.
Randwerte müssen auch an eventuellen Hindernissen, die im Gebiet Ω liegen, gesetzt werden. Siehe hierzu Kapitel 3.2.2 auf Seite 44.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 42 von 99
3.2. Diskretisierung
Aus den obigen kontinuierlichen Navier-Stokes-Gleichungen muss eine diskretisierte
Form abgeleitet werden, denn eine geschlossene, analytische Lösung der NavierStokes-Gleichungen ist im Allgemeinen nicht möglich.
Bevor die Diskretisierung der Gleichungen betrachtet werden kann, muss erst das
zugrunde liegende Gebiet Ω diskretisiert werden. Mit der Diskretisierung der Zeit
kann letztendlich die Impulsgleichung und die Kontinuitätsgleichung diskretisiert werden.
3.2.1. Das Gebiet
Das Gebiet Ω := [0, a ]× [0, b] ⊂ R 2 wird in imax Spalten und jmax Zeilen eingeteilt. Die Seitenlängen einer einzelnen Zelle δx und δy ergeben sich zu δx = a / imax und
δy = a / jmax .
Um die Randbedingung setzen zu können, müssen Randzellen, die das Gebiet umgeben, hinzugefügt werden. So ergibt sich ein Feld mit der Gesamtgröße von
[imax+2] x [jmax+2] Zellen.
Abbildung 26: Diskretisiertes Gebiet mit Randzellen
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 43 von 99
Damit die Navier-Stokes-Gleichungen im Diskreten numerisch stabil bleiben, werden
die Geschwindigkeitskomponenten u und v, sowie der Druck p in einem so genannten Staggered Grid gespeichert. Zu Deutsch ein versetztes Gitter. Hier werden die
drei Werte in einem jeweils um eine halbe Zelle zueinander versetztem Gitter abgespeichert. Die Idee dazu stammt aus der Finiten-Volumen-Technik. Hier werden die
Geschwindigkeiten an alle Seitenwände jedes Würfels gesetzt um den Massenfluss
zwischen Volumenzellen bei der Berechnung der Kontinuitätsgleichung zu bestimmen.
Das Staggered Grid gewährleistet auch im Zweidimensionalen, dass der Druck nicht
oszilliert. In [6] wird erklärt, warum das so ist. Neben dem Staggered Grid gibt es
Diskretisierungen des Gebiets auf regulären Gittern. Bei einem Collcated Grid werden alle Werte im Zellenmittelpunkt gespeichert. Allerdings sind dann spezielle Interpolationsmethoden notwendig. Im Staggered Grid hingegen können alle Größen linear interpoliert werden.
Wenn man die drei Gitter übereinander legt, kann man die Lage und Abstände der
drei Komponenten zueinander sehen. Der Druck p liegt in der Mitte einer Zelle. Die xKomponente u der Geschwindigkeit liegt in der Mitte der senkrechten Zellenränder
und die y-Komponente v der Geschwindigkeit liegt in der Mitte der waagrechten Zellenränder.
Aus dem versetzten Gitter ergeben sich noch ein paar Besonderheiten am Rand des
Gebiets, weil nicht alle Komponenten auf dem Rand des Gebiets Ω zu liegen kommen. Auf den senkrechten Rändern gibt es keine y-Komponente und auf den waagrechten Rändern gibt es keine x-Komponente. Die fehlenden Werte für die Ränder
werden in die zusätzlichen Randzellen abgespeichert.
Abbildung 27: Staggered Grid
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 44 von 99
3.2.2. Hindernisse
Nach der bisherigen Beschreibung wird das Fluid in einem rechteckigen Gebiet berechnet. Für realistische Simulationen werden aber meist irreguläre Geometrien bzw.
Topologien benötigt. Dazu wird ein weiteres Bitfeld verwendet, das mit einer Eins
angibt, dass es sich bei dieser Zelle um eine Hinderniszelle, und bei einer Null um
eine Fluidzelle handelt. Die Navier-Stokes-Gleichungen werden fortan nur noch in
den Fluidzellen berechnet.
Abbildung 28: Weiße Fluidzellen, graue Hinderniszellen, ungültige Zellen in Rot
Je feiner man das Gitter wählt, desto genauer lassen sich bestimmte Geometrien
darstellen.
Genauso wie am Rand des Gebiets, müssen bei Hinderniszellen die Randbereiche
nach einer entsprechenden Randbedingung gesetzt werden. Hier wird für die Randbedingung an Hinderniszellen stets die Haftbedingung verwendet. Das Fluid bleibt an
den Hindernissen haften.
Im Prinzip erfolgt das Setzen der Randwerte analog zum äußeren Rand. Jede Hinderniszelle wird daraufhin überprüft, an welcher Seite sie an eine Fluidzelle angrenzt.
Dabei sind nur die waagrechten und senkrechten Nachbarn von Bedeutung, die diagonal angrenzenden Felder spielen keine Rolle.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 45 von 99
Wenn sie nur an eine Fluidzelle angrenzt, ist das Vorgehen einfach, da nur die Komponente aus der Fluidzelle negiert in die Hinderniszelle eingetragen werden muss.
Durch die Negation ergibt sich in der linearen Interpolation zwischen Fluid- und Hinderniszelle eine Geschwindigkeit von Null am Rand – das Fluid haftet.
Wenn zwei Fluidzellen an das Hindernis angrenzen, die übereck liegen, ergibt sich
ebenfalls eine eindeutige Lösung. Durch das Staggered Grid grenzt jeweils nur eine
der beiden Geschwindigkeitskomponenten an die Hinderniszelle an, und diese können negiert eingetragen werden.
Nicht mehr eindeutig bestimmbare Randwerte kommen dann zustande, wenn eine
Hinderniszelle zwischen zwei Fluidzellen liegt. Das ist insbesondere der Fall, wenn
sie an drei oder mehr Fluidzellen angrenzen. In Abbildung 28 sind gültige Hinderniszellen in grau dargestellt, ungültige in Rot. Solche Zellen müssen eliminiert werden,
bevor die Berechnung der Navier-Stokes-Gleichungen stattfinden kann.
Ein explizites Setzen der Randwerte an Hinderniszellen ist bei der Berechnung der
UV-Werte, sowie bei der Berechnung des Drucks p notwendig.
3.2.3. Die Zeit, das Stabilitätskriterium
Das Zeitkontinuum wird durch diskrete Zeitpunkte ti ersetzt und die Geschwindigkeit
und der Druck werden nur an diesen Zeitpunkten berechnet. Der Abstand zwischen
zwei Zeitpunkten ti und ti+1 wird durch ein geeignet gewähltes ∆t gesetzt. Entweder
setzt man ∆t am Anfang der Simulation auf einen festen Wert, oder es wird je nach
Strömungsgeschwindigkeit und Reynoldszahl dynamisch gewählt. ∆t ist ein entscheidender Stabilitätsfaktor für die diskretisierten Navier-Stokes-Gleichungen und
darf nie zu groß gesetzt werden. Andernfalls können Oszillationen entstehen, die die
Berechnung unbrauchbar machen.
Die Stabilitätsbedingungen heißen Courant-Friedrichs-Levi-Bedingungen (CFL).
−1
 Re  1
1 
δx δy

 2 + 2  ,
∆t = τ min
,
 2  δx δy  u max vmax





Es muss zu jedem Zeitpunkt gewährleistet sein, dass ein Geschwindigkeitsvektor nie
weiter als in seine Nachbarzellen zeigt. Wird ein Vektor zu lang, so muss ∆t entsprechend kleiner gesetzt werden, damit die Bedingung erfüllt ist. Damit das für alle Vektoren im Feld gilt, werden die längsten Komponenten umax und vmax bestimmt. Dies
wird in den hinteren beiden Teilen der Minimumsbildung ausgedrückt.
Die zweite Schranke für ∆t ergibt sich aus der Reynoldszahl und der Zellengröße des
Gitters im ersten Teil der obigen Gleichung.
Der Faktor τ ∈ ]0,1] ist ein Sicherheitsfaktor, der das berechnete ∆t weiter absenken
kann. In der Praxis kommt es vor, dass eine Simulation trotzdem oszillieren kann,
auch wenn das Minimum korrekt berechnet worden ist. So kann ∆t weiter nach unten
korrigiert werden.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 46 von 99
Neben der Bestimmung von ∆t muss auch für jeden Term festgelegt werden, zu welchem Zeitpunkt man ihn auswertet. Bei den Impulsgleichungen werden die Terme
auf der linken Seite, also die Geschwindigkeit nach der Zeit und der Druck zum Zeitpunkt n+1 ausgewertet. Die Terme auf der rechten Seite werden alle zum Zeitpunkt n
berechnet. Andere Festlegungen für die Zeitpunkte der einzelnen Terme sind auch
denkbar, aber praktikabel ist nur diese.
Daraus ergibt sich für die Terme auf der rechten Seite ein explizites Lösungsverfahren, während die Terme auf der linken Seite, im Besonderen der Druck, implizit gelöst werden.
3.2.4. Die Impulsgleichung
Für die Diskretisierung werden finite Differenzenverfahren verwendet, wie sie auch
schon bei der Wassersimulation in Kapitel 2 verwendet wurden. Als Besonderheit sei
bei den konvektiven Termen auf den Zusatzterm α hingewiesen, der die numerische
Stabilität sichert.
Die Zeitableitungen
∂v
∂u
und
werden mit einer Vorwärtsdifferenz ausgedrückt:
∂t
∂t
u
 ∂u 
 ∂t  :=
i, j
v
 ∂v 
 ∂t  :=
i, j
( n +1)
− u (n )
δt
( n +1)
− v (n )
δt
Die erste Impulsgleichung für die x-Komponente u wird an den Mittelpunkten der
senkrechten Zellenkanten diskretisiert.
Den konvektiven Term −
( )
∂ u 2 ∂ (uv )
ersetzt man durch
−
∂x
∂y
( )
∂ u2 
1   ui , j + ui +1, j

:
=
 ∂x 
2

 i , j δx  
α
und
2
  ui −1, j + ui , j
 − 
2
 



2

+


1  ui , j + ui +1, j (ui , j − ui +1, j ) ui −1, j + ui , j (ui −1, j − ui , j ) 
−

δx 
2
2
2
2


 ∂ (uv ) 
1  (vi , j + vi +1, j )(ui , j + ui , j +1 ) (vi , j −1 + vi +1, j −1 )(ui , j −1 + ui , j ) 

 +
:
=
−
 ∂y 
2
2
2
2

 i , j δy 

α
1  vi , j + vi +1, j (ui , j − ui , j +1 ) (vi , j −1 + vi +1, j −1 ) (ui , j −1 − ui , j ) 
−

δy 
2
2
2
2


Echtzeitfähige Simulation von Wasser auf Grafikhardware
Der diffusive Term
Seite 47 von 99
1  ∂ 2u ∂ 2u 

 wird durch folgenden Term ausgedrückt:
+
Re  ∂x 2 ∂y 2 
ui +1, j − 2ui , j + u i −1, j
 ∂ 2u 
 2  :=
(δx )2
 ∂x  i , j
ui , j +1 − 2ui , j + u i , j −1
 ∂ 2u 
 2  :=
(δy )2
 ∂y  i , j
Bleibt als letztes noch der Druck, der durch eine Vorwärtsdifferenz diskretisiert wird:
pi +1, j − pi , j
 ∂p 
 ∂x  :=
δx
i, j
Die Variablen i und j laufen, bedingt durch das Staggered Grid, im Bereich
i = 1,..., imax − 1
j = 1,..., jmax
Vollkommen analog wird die Impulsgleichung für die y-Komponente v diskretisiert.
Die Konvektion −
( )
∂ (uv ) ∂ v 2
wird durch
−
∂x
∂y
1  (ui , j + ui , j +1 )(vi , j + vi +1, j ) (ui −1, j + ui −1, j +1 )(vi −1, j + vi , j ) 
 ∂ (uv ) 

 +
:
=
−
 ∂x 
δ
2
2
2
2
x
i, j


α
1  ui , j + ui , j +1 (vi , j − vi +1, j ) (ui −1, j + ui −1, j +1 )(vi −1, j − vi , j ) 
−

δx 
2
2
2
2


und
( )
2
∂ v2 
1   vi , j + vi , j +1   vi , j −1 + vi , j
 − 
 ∂y  := δy  
2
2

 i, j

 

α
ersetzt.



2

+


1  vi , j + vi , j +1 (vi , j − vi , j +1 ) vi , j −1 + vi , j (vi , j −1 − vi , j ) 
−

δy 
2
2
2
2


Echtzeitfähige Simulation von Wasser auf Grafikhardware
Die Diffusion
Seite 48 von 99
1  ∂ 2v ∂ 2v 
 wird durch

+
Re  ∂x 2 ∂y 2 
vi +1, j − 2vi , j + vi −1, j
 ∂ 2v 
 2  :=
(δy )2
 ∂x  i , j
vi , j +1 − 2vi , j + vi , j −1
 ∂ 2v 
:
=
 2
(δy )2
 ∂y  i , j
ersetzt.
Abschließend wird der Druck durch
pi , j +1 − pi , j
 ∂p 
:
=
 ∂y 
δy
  i, j
diskretisiert.
Der Bereich für die Variablen i und j liegt für die y-Komponente
i = 1,..., imax
j = 1,..., jmax − 1
Der Faktor α liegt hierbei im Bereich zwischen 0 und 1. Mit α = 0 wird der zweite Teil
der Gleichungen ausgeblendet, womit man eine Zentraldifferenz erhält. Mit α = 1 erhält man die Doner-Cell-Diskretisierung. Nähere Informationen hierzu gibt es in [6].
Nach [20] muss α folgende Gleichung erfüllen:

α ≥ max ui , j
i, j

δt
δt
, vi , j
δx
δy




In der Praxis verwendet man meist den konstanten Wert 0.5.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 49 von 99
3.2.5. Die Kontinuitätsgleichung
Die Bedingung der Divergenzfreiheit wird durch
ui , j − ui −1, j
 ∂u 
:
=
 ∂x 
δx
i, j
vi , j − vi , j −1
 ∂v 
 ∂y  :=
δy
  i, j
diskretisiert und i, j sind im Bereich
i = 1,..., imax
j = 1,..., jmax
Mit Hilfe der Kontinuitätsgleichung wird im Kapitel 3.3.2 auf Seite 51 die rechte der
Seite der Poisson-Gleichung für den Druck p berechnet.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 50 von 99
3.3. Der Algorithmus
Nachdem die kontinuierlichen Navier-Stokes-Gleichungen diskretisiert wurden, fehlt
noch ein Algorithmus, der das ganze berechnet. Außerdem wird hier auf die Problematik der Druckberechnung näher eingegangen, denn dieser wird nach obiger Zeitdiskretisierung zum Zeitpunkt n+1 benötigt.
Nach der Initialisierung der Felder U, V und P mit den Anfangswerten, beginnt die
äußere Zeitschleife, die genau einen Zeitschritt von tn auf tn+1 berechnet. Innerhalb
dieser Schleife werden die neuen Geschwindigkeitsvektoren U und V sowie der neue
Druck P zum Zeitpunkt tn+1 berechnet. In dieser Implementierung ist die Zeitschleife
eine Endlosschleife, sie kann aber jederzeit durch den Benutzer unterbrochen werden bzw. neu gestartet werden.
3.3.1. Die Berechnung der Diffusion und Konvektion
Die Impulsgleichungen werden zuerst so umgestellt, dass auf der linken Seite nur
noch u bzw. v zum Zeitpunkt n+1 vorkommen. Mit den Variablen F und G werden
fortan die u,v-Werte zum Zeitpunkt n, die sich aus der Addition der diffusiven und
konvektiven Anteile, sowie der äußeren Einflusskraft g berechnen.
( )
 1   ∂ 2u 

 ∂ 2 u    ∂ u 2 
 ∂ (uv ) 


+ 2  −
−
+ g x ;
Fi , j = ui , j + ∂t


 Re   ∂x 2 


 ∂y  i , j   ∂x  i , j  ∂y  i , j
i, j
 

Wieder durch das Staggered Grid bedingt ergeben sich diese Laufindizes für i und j
i ∈ [1; imax − 1],
j ∈ [1; jmax ]
Analog ergibt sich für G:
( )
 1   ∂ 2v 

 ∂ 2 v    ∂ (uv ) 
∂ v2 
;
−
+
Gi , j = vi , j + ∂t    2  +  2   − 
g
y
 ∂y 

 Re   ∂x 


∂
x
∂
y


 i, j 

 i, j
i, j
i, j
 

Mit i,j im Bereich
i ∈ [1; imax ],
j ∈ [1; jmax − 1]
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 51 von 99
In dieser Schreibweise ergeben sich für die u,v-Werte zum Zeitpunkt n+1 folgende
diskretisierte Impulsgleichungen:
ui(,nj+1) = Fi ,(nj ) −
δt (n+1)
pi +1, j − pi(,nj+1) )
(
δx
i ∈ [1; i max − 1]; j ∈ [1; j max ]
vi(,nj+1) = Gi(,nj) −
δt (n+1)
( pi, j+1 − pi(,nj+1) )
δy
i ∈ [1; i max ]; j ∈ [1; j max − 1]
Der Druck ist die letzte Komponente, die noch berechnet werden muss, bevor der
Algorithmus komplett ist.
3.3.2. Die Berechnung des Drucks
Der rechenintensivste Teil der Strömungssimulation ist die Berechnung des Drucks.
Zunächst benötigt man die rechte Seite der Druckgleichung, damit der Druck bestimmt werden kann. Die rechte Seite ergibt sich aus der Kontinuitätsgleichung und
den F-G-Werten aus dem vorherigen Abschnitt:
rs =
(n )
(n )
(n )
(n )
1  Fi , j − Fi −1, j Gi , j − Gi , j −1 
+

δt 
δx
δy

Die linke Seite dieser so genanten Poisson-Gleichung ergibt sich aus der Diskretisierung des Drucks wie folgt:
pi(+n1+,1j) − 2 pi(,nj+1) + pi(−n1+,1j)
(δx )2
+
pi(,nj++11) − 2 pi(,nj+1) + pi(,nj+−11)
(δy )2
(n )
(n )
(n )
(n )
1  Fi , j − Fi −1, j Gi , j − Gi , j −1 
=
+

δt 
δx
δy

Wie aus obiger Formel ersichtlich, benötigt man den Druck im Zeitpunkt n+1. Das
läuft auf ein Gleichungssystem hinaus, das mit einem geeigneten Lösungsverfahren
berechnet werden muss. Eine Gausselimination wäre denkbar, aber da die Matrix
eine Bandmatrix mit fünf Bändern ist, sind iterative Verfahren besser geeignet. Sie
lösen das Gleichungssystem sehr viel schneller, auch wenn der Restfehler erst nach
mehreren Iterationen gering wird.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 52 von 99
Gauss-Seidel-Verfahren
Der erste Versuch einen Gleichungssystemlöser zu implementieren war das GaussSeidel-Verfahren auf der GPU zu programmieren. Bei diesem Verfahren werden bei
der Berechnung der Drucks p an der Stelle (i,j) benachbarte Werte benötigt.
Dieses Verfahren funktioniert nur, wenn das Feld linear von links oben nach rechts
unten abgearbeitet wird, weil bei der Berechnung des Drucks in Zelle (i,j) der linke
und der obere Werte von p schon aus der aktuellen Iteration stammen muss, während der rechte und untere Werte von p noch aus der letzten Iteration kommt. In einer Software-Lösung ist diese Abarbeitungsfolge kein Problem, in Grafikhardware
hat man darüber keine Kontrolle.
Abbildung 29: Gauss-Seidel-Verfahren
Abgesehen von der Abarbeitungsfolge kann man überhaupt nicht auf bereits geschriebene Elemente zugreifen, weil intern alle Daten erst in eine Schattentextur geschrieben und erst am Ende des Passes sichtbar werden.
Aus diesen Gründen ist das Gauss-Seidel-Verfahren auf Grafikhardware in dieser
Form nicht umsetzbar.
Einen anderen Ansatz um das das Gauss-Seidel-Verfahren dennoch von der GPU
berechnen zu lassen wird in [7] vorgestellt. Für diese Zwecke ist es allerdings nicht
effizient umzusetzen.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 53 von 99
Konjugierte Gradienten-Verfahren
Im zweiten Anlauf wurde ein konjugiertes Gradienten Verfahren verwendet, das im
Rahmen des clFramework implementiert wurde. Wie auch das Gauss-SeidelVerfahren wird es in [7] genau beschrieben.
Abgesehen von der manchmal auftretenden Divergenz des Verfahrens, wird der
Druck schon mit sehr wenigen Iterationen brauchbar angenähert. Um möglichst viel
Geschwindigkeit aus dem Programm herauszuholen, wurden meist nur zwei Iterationen verwendet.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 54 von 99
3.3.3. Der gesamte Algorithmus
Jetzt sind alle Teile, die zur Berechnung der Navier-Stokes-Gleichungen notwendig
sind, vorhanden und können nach folgendem Schema berechnet werden.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Setze Zeit t:=0
Belege die Felder U,V und P überall mit den Initialwerten u0, v0, p0
Wiederhole (Zeitschleife)
Berechne ∆t nach den Stabilitätsbedingungen
Setze Randwerte für U und V am äußeren Rand
Setze Randwerte für U und V an den Hinderniszellen
Berechne F und G
Setze Randwerte für F und G am äußeren Rand
Setze Randwerte für F und G an den Hinderniszellen
Berechne die rechte Seite der Druckgleichung
Setze it:=0
Solange it < itermax oder residuum < eps
Setze Randwerte für den Druck am äußeren Rand
Setze Randwerte für den Druck an den Hinderniszellen
Führe eine Druck-Iteration durch
It++
Aktualisiere U und V über F, G und P
t = t + ∆t
Die Anzahl der Iterationen, die zur Berechnung des Drucks verwendet werden, sind
an zwei Abbruchkriterien gekoppelt. Zum einen kann eine maximale Anzahl von Iterationen itermax vorgegeben werden. Zum anderen kann nach jeder Iteration ein Residuum berechnet werden, das bestimmt, wie weit die aktuelle Lösung von der richtigen Lösung entfernt ist. Erst wenn das Residuum unter eine gewisse EpsilonSchranke fällt, wird die Schleife verlassen. Die Epsilon-Schranke kann hierbei beliebig klein gewählt werden. Eine Epsilon-Schranke von ca. 10-4 ist ein üblicher Wert.
Durch das verwendete konjugierte Gradienten-Verfahren wird dieses Residuum aber
meist nicht erreicht. Das Abbruchkriterium wird im Normalfall durch das Überschreiten der maximalen Anzahl der Iterationen erfüllt.
Somit ist die theoretische Diskretisierung abgeschlossen. Im nächsten Kapitel geht
es um die Umsetzung des obigen Algorithmus auf der GPU.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 55 von 99
3.4. Implementierung
In diesem Abschnitt geht es um die konkrete Umsetzung des obigen Algorithmus auf
der Grafikkarte. Als Grafik-API wurde DirectX 9.0 von Microsoft verwendet. In dieser
Version wurde eine neue Hochsprache, die High-Level-Shader-Language (HLSL),
integriert, mit Hilfe derer man Vertex- und Pixel-Shader-Programme auf hohem Abstraktionsniveau entwickeln kann. Bisher musste man Shader in Assembler programmieren.
Wie schon im ersten Teilprojekt in Kapitel 2 wurde die Umsetzung ausschließlich mit
Pixel-Shader Programmen auf Fragmentbasis implementiert. Vertex-Shader Programme in der Geometrieverarbeitung wurden nicht benötigt.
Zunächst wird beschrieben, wie die Daten der Felder gespeichert werden. Danach
werden Vertex-Buffer besprochen, mit denen man gezielte Bereiche der Felder bzw.
Texturen von der GPU bearbeiten kann. Anschließend folgt ein kurzer Abschnitt über
die Shader-Programme, insbesondere über den BoundaryUV-Shader, der eine Sonderstellung einnimmt. Mit Hilfe dieser Einzelteile können dann die Renderingstufen
betrachtet werden. Abschließend folgen Geschwindigkeitsmessungen.
3.4.1. Texturen
Zur Speicherung der einzelnen Komponenten im Gebiet Ω werden vier Texturen verwendet. Ihre Größe hängt alleine von der Anzahl der simulierten Zellen ab. Ein
Randpixel wird automatisch hinzugefügt. Auch wenn man zunächst durch das Staggered Grid eine komplizierte Speicherung und Adressierung der einzelnen Texturelemente vermuten möchte, ergibt sich die korrekte Adressierung schlicht aus der
Diskretisierung und man kann alle vier Texturen gleich groß anlegen, auch wenn bei
manchen Komponenten nicht alle Zellen benötigt werden.
Das Texturformat ist immer ein 32-Bit Fließkommaformat mit einer oder vier Komponente und die Größe ist immer [imax+2] x [jmax+2] Texel bzw. Zellen.
Die erste Textur ist die UVFG-Textur, die pro Zelle in der x-y-Komponente den Geschwindigkeitsvektor UV, und in der z-w-Komponente, die FG-Werte aus der Impulsgleichung hält.
 x
u
 
 
 y
v
=
z
f
 
 
 w
 
 i, j  g i, j
In den folgenden zwei Texturen mit je einer Komponente werden die rechte Seite der
Druckgleichung und der Druck berechnet.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 56 von 99
(x )i , j = (rs )i , j
(x )i , j = ( p )i , j
Als letztes fehlt noch eine Ablage für die Hindernisinformationen. Dazu wird die
Obstacles-Textur verwendet.
 x
 fluid | obstacle 
 


shape
 y


 z  =  right − shift 
 


 w


  i , j  top − shift  i , j
In der x-Komponente steht ein binärer Wert, der anzeigt, ob es sich hier um eine
Hinderniszelle oder um eine Fluidzelle handelt. Eine Eins bedeutet, dass diese Zelle
ein Hindernis ist, andernfalls ist es eine Fluidzelle. Der Shape-Wert in der yKomponente erhielt seinen Namen deswegen, weil er genau die Randzellen von
Hindernissen vorberechnet und hier Nachbarschaftsrelationen ablegt. Shape-Zellen
sind also Hinderniszellen, die an eine oder mehrere Fluidzellen angrenzen. Im Shape-Wert werden die acht möglichen Nachbarn der Zelle betrachtet, welche Fluidzellen bzw. Hinderniszellen sind, und in einem Bitfeld abgespeichert. An dieser Stelle
sei nochmals darauf hingewiesen, dass eine Hinderniszelle maximal an zwei Fluidzellen angrenzen darf, und diese dürfen auch nicht gegenüberliegen, weil sich sonst
die Randbedingung für diese Hinderniszellen nicht mehr eindeutig festlegen lässt.
Die anderen beiden Werte right-shift und top-shift sind Hilfsvariablen. Beim Setzen
der Randbedingungen an einer Hinderniszelle (i,j) müssen je nach Shape gegebenenfalls auch die Zellen (i-1,j) oder (i,j+1) verändert werden. Diese Notwendigkeit ist
auf das Staggered Grid zurückzuführen. Da in einem Pixel-Shader-Programm aber
nur die Zelle (i,j) verändert werden kann, werden beim Berechnen von (i,j) die ShiftWerte überprüft, ob sich eine Zelle rechts (i+1,j) oder oberhalb (i,j-1) befindet. Entsprechend ihres Shift-Wertes werden dann die Randbedingungen umgesetzt.
Eine zusätzliche vierte Textur speichert die Informationen für den Partikelverfolger,
der im Kapitel 3.4.6 auf Seite 69 näher erläutert wird. Hier wird nur eine Komponente
benötigt, die die Dichte der Partikel in einer Zelle festhält. Der Wertebereich liegt zwischen Null und Eins.
(x )i , j = ( particle density )i , j
Für jede der hier vorgestellten Texturen gibt es eine Schattentextur, die im Hauptspeicher des Rechners liegt. Vor jedem Reset des Direct3D-Device werden die Texturen in ihre entsprechenden Schattentexturen im Hauptspeicher kopiert und beim
Wiederaufbau aus ihnen wieder zurückkopiert. So ist gewährleistet, dass die Simulation beim Vergrößern des Fensters nicht verloren geht.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 57 von 99
3.4.2. Vertex-Buffer
Durch die Randbedingungen und das Staggered Grid müssen in den einzelnen
Schritten des Algorithmus verschiedene Bereiche der Textur beschrieben werden.
Auf Grund der aktuellen Implementierung der GPUs werden in Shader bei Verzweigungen im Code immer alle Äste ausgeführt – wobei nur der richtige Ast seine Ergebnisse zurückschreiben darf. Verzweigungen kosten also sehr viel Rechenzeit und
sollten vermieden werden.
Um zum Beispiel die Randbedingungen zu setzen, müsste ein Shader beim Durchlaufen der gesamten Textur jedes Mal abprüfen, ob er sich gerade am Rand befindet
oder nicht, und es würden pro Pixel die Bedingungen berechnet, auch wenn sie nicht
in die Textur geschrieben werden.
Ein Ausweg um keine unnötigen Operationen zu berechnen sind Vertex-Buffer, die
nur bestimmte Bereiche der Textur überdecken. Dazu wird ein Quadrat, das nur einen bestimmten Teil der Textur überdeckt, über vier Vektoren in einem Vertex-Buffer
abgelegt. Sie dienen als Schablone, auf welchen Bereichen die Shader-Programme
die Texturen bearbeiten sollen.
Der Vertex-Buffer Full überdeckt die gesamte Textur inklusive Rand. Wichtiger ist der
Vertex-Buffer Inner, der von den meisten Shadern verwendet wird. Der äußere Rand
wird bei diesem Vertex-Buffer nicht verändert. Beispiele sind das Setzen der Hindernisrandbedingungen im UV-Feld und die Berechnung von F und G.
Für das Setzen der äußeren Randbedingungen im FG-Feld werden spezielle VertexBuffer benutzt, in der folgenden Abbildung bläulich dargestellt. Es gibt je einen für die
vier Ränder, wobei jeweils der Eckrandwert nicht überschrieben wird: Top0, Bottom0,
Left0, Right0.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 58 von 99
Abbildung 30: Vertex-Buffer Full, Inner (grau), Top0, Bottom0, Left0, Right0
Für die äußeren Randbedingungen im UV-Feld benötigt man im Staggered Grid noch
einen weiteren Satz von rechteckigen Bereichen. Die Top1-, Bottom1-, Right1- und
Left1-Vertex-Buffer entsprechen den die Top0-, Bottom0-, Right0- und Left0-VertexBuffer mit dem Unterschied, dass jeweils die Eckzelle enthalten ist.
Des Weiteren sind noch zwei Vertex-Buffer notwendig, die sich am rechten und unteren Rand jeweils eine Zelle weiter innen im Feld befinden. Diese sind wegen des
Staggered Grids notwendig, da sich der rechte Rand für die U-Komponente eine Zelle im Inneren befindet. Analog ist der Rand für die V-Komponente die zweit-unterste
Zelle. Ihre Namen sind dementsprechend Right12 und Bottom12.
Als letzen Vertex-Buffer benötigt man noch einen für die Darstellung im Framebuffer.
Er kann beliebig gewählt werden. Je nach dem, ob man die Randbereiche anzeigen
lassen will oder nicht, verschiebt man die Texturkoordinaten entsprechend nach innen.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 59 von 99
Abbildung 31: Randbedingungen im Staggered Grid
3.4.3. Die Shader-Programme
Ein limitierender Faktor bei der Erstellung von Shader-Programmen ist die derzeitig
maximale Länge von 64 Instruktionen bei Pixel-Shader Programmen. Bei VertexShadern liegt die Zahl höher, aber für diese Problematik können nur Pixel-ShaderProgramme verwendet werden, da immer auf Felder operiert wird. Die Limitierung
der Shader-Länge stammt aus dem Pixel-Shader 2.0 Standard. Erst mit dem PixelShader 3.0 Standard dürfen auch Pixel-Shader-Programme länger sein. Doch momentan gibt es keine Grafikkarte, die schon jetzt diesen Standard unterstützt.
Daraus ergibt sich, wie man im nächsten Abschnitt sehen kann, oftmals eine Aufteilung eines logischen Verarbeitungsschritts in mehrere einzelne Shader. Die Berechnung von F und G ist in zwei getrennte Shader-Programme aufgeteilt, die jeweils fast
an das 64-Instruktionslimit stoßen. Wenn längere Shader-Programme möglich wären, würde viel Overhead wegfallen, der bei jedem Shader-Programm am Anfang
steht. Zum Beispiel entfiele das Auslesen der Textur an den Nachbarstellen.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 60 von 99
Die Shader-Programme sind logisch sortiert in mehrere Dateien aufgeteilt:
Impulse.hlsl
o Setzen der Randbedingungen im UV-Feld
o Berechnung von FG
o Setzen der Randbedingungen im FG-Feld
o Einfügen von Geschwindigkeit mit der Maus
o Update von UV mit FG und Druck
Poisson.hlsl
o Berechnung der rechten Seite der Poisson-Gleichung
o Setzen der Druckrandbedingungen
Obstacles.hlsl
o Einfügen und Entfernen von Hinderniszellen
o Berechnung der Shape- und Shift-Vorberechnungen für Hinderniszellen
o Löschen illegaler Hinderniszellen
o Importieren von Grafiken als Hinderniskarte
Particles.hlsl
o Einfügen von Partikeln mit der Maus
o Partikeldiffusion
o Partikelverfolgung
o Einfügen von Partikelpinseln aus Grafiken
View2D.hlsl
o Darstellung der Geschwindigkeit UV als Farbkodierung
o Darstellung der Partikel als Grauwerte
o Darstellung der Hindernisse mit Blau
o Darstellung des Drucks im roten Farbkanal
o Berechnung und Darstellung der Wirbelstärke
Zusätzlich enthalten die Klassen aus dem clFramework für den iterativen Gleichungsystemlöser weitere Shader-Programme zur Berechnung des Drucks.
Ein besonderer Shader ist der BoundaryUV-Shader, der die Bedingung am äußeren
Rand im UV-Geschwindigkeitsfeld berechnet. Während alle anderen ShaderProgramme im Verzeichnis shaders/ als statische Programme abgelegt sind, wird
der BoundaryUV-Shader dynamisch zur Laufzeit erzeugt.
Für jeden der vier Ränder Oben, Rechts, Unten und Links kann entweder eine Haftbedingung, eine Rutschbedingung oder eine Ausströmbedingung gewählt werden.
Des Weiteren kann ein Simulationstyp gewählt werden, der eine Einströmbedingung
in einem bestimmten Teilbereich der Ränder setzt. Folgende Simulationen sind definiert:
Driven Cavity: Zieht am oberen Rand ein Band mit der Geschwindigkeit 1.0
nach rechts. Diese Bedingung wird für die Nischenströmung benötigt.
Waterfall: Definiert am linken Rand ab der Hälfte bis zum oberen Rand ein
Einströmen mit der Initialgeschwindigkeit UV0.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 61 von 99
Ocean: Setzt an allen Rändern die Geschwindigkeit fest auf UV0. Dieses Profil wird beispielsweise bei der Wirbelstraße oder der Stufenströmung benötigt.
Inject: Definiert ein Einspritzen in das Feld von der linken Seite. Dazu wird am
linken Rand in der Mitte die Geschwindigkeit fest auf UV0 gesetzt.
Nur wenn der Benutzer diese Bedingung explizit ändert, ergibt sich ein neuer Pfad
durch die relativ aufwändige Verzweigung. Diese ist deswegen so aufwändig, weil es
sehr viele mögliche Fälle gibt.
Der dynamische Shader soll es nun möglich machen, nur den Pfad im Shader ausführen zu lassen, der gerade vom Benutzer gewählt wurde. In der Implementierung
stehen alle möglichen Fälle als Text- bzw. Stringbausteine im Shader-Quellcode zur
Verfügung, die je nach Benutzereingabe selektiert und zusammengesetzt werden.
Anschließend wird dieser neue Shader übersetzt. Dieser Prozess findet nur statt,
wenn der Benutzer die Randbedingung bzw. den Simulationstyp ändert. In der laufenden Simulation wird der kompilierte Shader ausgeführt.
Abbildung 32: Dynamischer Zusammenbau des BoundaryUV-Shaders
Durch den dynamischen Shader entsteht keine einzige Verzweigung und die Abarbeitung ist sehr schnell.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 62 von 99
3.4.4. Die Rendering Pipeline
Die Rendering Pipeline folgt dem vorgestellten Pseudo-Algorithmus aus Kapitel 3.3.3
auf Seite 54. Jede einzelne Render-Funktion beschreibt mit Hilfe seines PixelShader-Programms eine der vier Texturen.
Die Aufrufe der einzelnen Funktionen erfolgt über DirectX, die Ausführung der konkreten Rechenoperationen erfolgt auf der Grafikkarte.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Setze Zeit t:=0
RenderUVFGPRSReset
Wiederhole (Zeitschleife)
∆t = RenderDeltaT
RenderImpulseUVBoundaryOuter
RenderImpulseUVBoundaryObstaclesShape
RenderImpulseUVBoundaryObstaclesShift
RenderImpulseF
RenderImpulseG
RenderImpulseFGBoundary
RenderPressureRightSide
Setze it:=0
PressureSolveInitialize
Solange it < itermax oder residuum < eps
RenderPressureBoundary
residuum = RenderPressureSolveIteration
it++
RenderImpulseUVFGP
Particlessiehe Kapitel 3.4.6 auf Seite 69
t = t + ∆t
Im folgenden C-Quellcode wird exemplarisch an RenderImpulseUVBoundaryObstaclesShape gezeigt, wie der Aufruf eines Shader-Programms von DirectX aus erfolgt.
Zunächst wird das Ziel der Shader-Berechnungen über RenderToSurface (Zeile 3)
die UVFG-Textur festgelegt. Anschließend werden mit der SetFloat-Methode (ab Zeile 9) alle nötigen Konstanten an das Shader-Programm übergeben. Im nächsten Abschnitt werden sie genauer beschrieben. Nun folgen die Eingabetexturen ab Zeile 34.
Für die Berechnung von F werden die UVFG-Textur, die zugleich auch das Schreibziel des Shader-Programms ist, und die Hindernistextur übergeben.
Über SetTechnique in Zeile 41 wird ein konkretes Shader-Programm ausgewählt,
das ausgeführt werden soll, in diesem Fall ImpulseF. Da eine Technique aus mehreren Passes bestehen kann, wird in der nachfolgenden Schleife (ab Zeile 46) über
die Anzahl der Passes gelaufen und der jeweilige Pass selektiert (Zeile 48).
Echtzeitfähige Simulation von Wasser auf Grafikhardware
1
2
3
4
5
6
Seite 63 von 99
HRESULT CMyD3DApplication::RenderImpulseF()
{
if (SUCCEEDED(m_pRenderToSurface->BeginScene(
m_pSurfUVFG, NULL)))
{
HRESULT hr;
7
8
9
10
// set texture step
hr = m_pShaderImpulse->SetFloat("tsx", m_vTS.x);
hr = m_pShaderImpulse->SetFloat("tsy", m_vTS.y);
11
12
13
14
15
16
// set dx, dy
hr = m_pShaderImpulse->SetFloat("dx4",
1.0f / (4.0f * m_vDArea.x));
hr = m_pShaderImpulse->SetFloat("dy4",
1.0f / (4.0f * m_vDArea.y));
17
18
19
20
// set 1/dx², 1/dy²
hr = m_pShaderImpulse->SetFloat("rdx2", m_vRD2Area.x);
hr = m_pShaderImpulse->SetFloat("rdy2", m_vRD2Area.y);
21
22
23
// set 1 / Reynolds
hr = m_pShaderImpulse->SetFloat("Re", 1.0f / m_fRe);
24
25
26
// set alpha
hr = m_pShaderImpulse->SetFloat("alpha", m_fAlpha);
27
28
29
// set dt
hr = m_pShaderImpulse->SetFloat("dt", m_fDT);
30
31
32
// set GX
hr = m_pShaderImpulse->SetFloat("gx", m_vG.x);
33
34
35
36
37
38
// set textures
hr = m_pShaderImpulse->SetTexture("tUVFG",
m_pTexUVFG);
hr = m_pShaderImpulse->SetTexture("tObstacles",
m_pTexObstacles);
39
40
41
// setup technique
hr = m_pShaderImpulse->SetTechnique("ImpulseF");
42
44
45
46
47
48
UINT cPasses,iPass;
m_pShaderImpulse->Begin(&cPasses, 0);
for (iPass = 0; iPass < cPasses; iPass++)
{
hr = m_pShaderImpulse->Pass(iPass);
49
// render using inner vertex-buffer
m_pd3dDevice->SetStreamSource( 0, m_pVBInner,
0, sizeof(CUSTOMVERTEX) );
50
51
52
53
m_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
53
54
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP,
0, 2 );
55
56
57
}
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 64 von 99
m_pShaderImpulse->End();
58
59
// done rendering to texture
m_pRenderToSurface->EndScene(0);
60
61
62
return S_OK;
63
64
}
65
66
return S_FALSE;
67
68
}
Im Inneren der Schleife folgt jetzt die Wahl des Vertex-Buffer in SetStreamSource
in Zeile 51. Damit wird festgelegt, welcher Bereich der Textur beschrieben werden
soll. Mit pVBInner wird der innere Bereich des Gebiets Ω ohne Rand bearbeitet.
Der eigentliche Start des Shader-Programms erfolgt dann in Zeile 55 mit dem Aufruf
von DrawPrimitive, das den Vertex-Buffer rendert und den Pixel-Shader ausführt.
Abschließend kommen noch Aufräumarbeiten ab Zeile 58 um das Shader-Programm
und die Szene zu beenden.
3.4.5. Ein Beispiel Shader in HLSL: ImpulseF
Hier wird beispielhaft der ImpulseF-Shader im Quellcode gezeigt, um einen Eindruck
zu bekommen, wie die High-Level-Shader-Language (HLSL) aussieht. Dieses Programm berechnet die Variable F, wie sie in der Diskretisierung beschrieben ist.
In den Zeilen 1 – 13 werden die Variablen definiert, die vom DirectX-C-Programm an
das Shader-Programm übergeben werden.
Texturkoordinaten werden immer auf [0;1] normalisiert, deswegen muss dem Shader
mitgeteilt werden wie groß der Abstand zu Nachbarpixeln ist, damit er auf sie zugreifen kann. Die Variablen tsx und tsy (Zeile 1 und 2) enthalten diese Werte wobei
tsx = 1 / (Zellenanzahl in x-Richtung) und tsy = 1 / (Zellenanzahl in y-Richtung) sind.
Alle Variablen, die vorberechenbar sind, werden als weitere Konstanten übergeben,
um im Shader keine Rechenzeit zu verschwenden. Für die Berechnung der Diffusion
werden die Variablen rdx2 und rdy2 (Zeile 4 und 5) vorbestimmt.
rdx 2 =
1
;
(δx )2
rdy 2 =
1
(δy )2
Alle weiteren Konstanten Re, dt, gx, alpha (Zeile 7 – 10) und die Texturen (Zeile 12
und 13) werden unverändert an den Shader übergeben.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 65 von 99
Die Struktur vertex2pixel in Zeile 17 – 21 definiert das Datenübergabeformat vom
Vertex-Shader zum Pixel-Shader. Vertex-Shader werden hier nicht gebraucht, weil in
der Geometrieverarbeitung keine Besonderheiten notwendig sind. In diesem Fall wird
automatisch die Fixed-Function-Pipeline verwendet. Essentiell ist hier die Texturkoordinate, die zwischen den Vertices bilinear interpoliert wird. Jeder Pixel, der bearbeitet wird, kennt somit seine Texturposition.
Um auf Texturen zugreifen zu können, braucht man für jede einen sampler (ab Zeile
23 und 33), der die Textur und den Zugriffsmodus festlegt. MinFilter und MagFilter
bestimmen, ob die Textur nur an einem Punkt ausgelesen werden soll, oder ob man
bilineare Interpolation wünscht. Im Falle von Fließkommatexturen, wie sie hier immer
verwendet werden, wird hardwareseitig nur das Punktauslesen unterstützt. Lineare
Interpolation ist nicht definiert. AddressU und AddressV bestimmen das Verhalten
am Rand der Textur. Falls die Texturkoordinaten außerhalb [0;1] liegen sollten,
bestimmen diese Parameter, an welcher Stelle die Textur ausgelesen werden soll.
Clamp setzt negative Werte auf Null und Werte größer Eins auf Eins zurück. Mirror
spiegelt Koordinaten außerhalb des Bereichs ins Innere zurück und Wrap macht die
Textur periodisch.
1
2
float
float
tsx;
tsy;
// texture step x
// texture step y
float
float
rdx2;
rdy2;
// 1 / (dx*dx)
// 1 / (dy*dy)
float
float
float
float
Re;
dt;
gx;
alpha;
// Reynolds number
// Delta t
// forces from outside
3
4
5
6
7
8
9
10
11
12
13
texture tUVFG;
texture tObstacles;
14
15
//////////////////////////////////////////////////////////
16
17
18
19
20
21
struct vertex2pixel
{
float4 Position
float2 TexCoord
};
: POSITION;
: TEXCOORD0;
22
23
24
25
sampler PointSamplerUVFG = sampler_state
{
Texture = (tUVFG);
26
MinFilter
MagFilter
AddressU
AddressV
27
28
29
30
31
32
};
=
=
=
=
Point;
Point;
Clamp;
Clamp;
Echtzeitfähige Simulation von Wasser auf Grafikhardware
33
34
35
Seite 66 von 99
sampler PointSamplerObstacles = sampler_state
{
Texture = (tObstacles);
36
MinFilter
MagFilter
AddressU
AddressV
37
38
39
40
41
=
=
=
=
Point;
Point;
Clamp;
Clamp;
};
42
44
45
46
//////////////////////////////////////////////////////////
// ImpulseF
//////////////////////////////////////////////////////////
47
48
49
50
51
float4 ImpulseFPixelShader(vertex2pixel v) : COLOR0
{
// get current position
float2 uv = v.TexCoord;
52
53
53
54
// sample seven surrounding texels
float4 topcenter
= tex2D(PointSamplerUVFG,
float2(uv.x, uv.y - tsy));
55
56
float4 topright
= tex2D(PointSamplerUVFG,
float2(uv.x + tsx, uv.y - tsy));
float4 centerleft
= tex2D(PointSamplerUVFG,
float2(uv.x - tsx, uv.y));
float4 center
= tex2D(PointSamplerUVFG, uv);
float4 centerright
= tex2D(PointSamplerUVFG,
float2(uv.x + tsx, uv.y));
57
58
59
60
61
62
63
64
65
66
67
68
float4 bottomcenter = tex2D(PointSamplerUVFG,
float2(uv.x, uv.y + tsy));
69
70
71
// sample obstacles
float4 obst
= tex2D(PointSamplerObstacles, uv);
72
73
74
float4 obstright
= tex2D(PointSamplerObstacles,
float2(uv.x + tsx, uv.y));
75
76
77
// copy U value to F
center.z = center.x;
78
79
80
81
82
83
84
85
// if this and the cell to the right are fluid cells
if ((obst.x + obstright.x) == 0)
{
// compute F
// du² / dx
float fd = center.x + centerright.x;
float bd = center.x + centerleft.x;
86
87
88
89
90
float du2dx = (
(fd * fd)
- (bd * bd)
+ alpha *
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 67 von 99
(
91
abs(fd) *
(center.x - centerright.x)
- abs(bd) *
(centerleft.x - center.x)
92
93
94
95
)
) * dx4;
96
97
98
// duv / dy
fd = center.y + centerright.y;
bd = topcenter.y + topright.y;
99
100
101
102
float duvdy = (
103
fd * (center.x + bottomcenter.x)
- bd * (topcenter.x + center.x)
+ alpha *
(
abs(fd) *
(center.x - bottomcenter.x)
- abs(bd) *
(topcenter.x - center.x)
)
) * dy4;
104
105
106
107
108
109
110
111
112
113
114
115
116
// wave (diffusion)
float wave = Re *
((centerright.x - 2*center.x
+ centerleft.x) * rdx2 +
(bottomcenter.x - 2*center.x
+ topcenter.x ) * rdy2);
117
118
119
120
121
122
123
// F
center.z += dt * (wave - du2dx - duvdy + gx);
124
125
126
}
127
128
return center;
129
130
}
131
132
133
134
135
136
137
138
139
technique ImpulseF
{
pass P0
{
VertexShader = NULL;
PixelShader = compile ps_2_0 ImpulseFPixelShader();
}
}
Der Einsprungspunkt für ein High-Level-Shader-Programm ist eine so genannte
Technique (Zeile 132). In ihr können mehrere Passes (Zeile 134) definiert werden,
die jeweils ein Vertex-Programm und ein Pixel-Programm ausführen. In diesem Fall
gibt es nur einen Pass ohne Vertex-Programm. Das Pixel-Programm wird mit einem
bestimmten Profil übersetzt ps_2_0; das bedeutet: Pixel-Shader 2.0 Standard.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 68 von 99
In ImpulseFPixelShader (Zeile 48) werden zunächst die Texturkoordinaten zwischengespeichert (Zeile 51) und anschließend alle Nachbarpunkte der aktuellen Position in die Konstantenregister kopiert, da sie öfters gebraucht werden (Zeile 53 –
68). Außerdem werden die Hindernistextur an der aktuellen Position und ein Texel
weiter rechts ausgelesen (Zeile 71 – 74). Nur wenn beide keine Hinderniszellen sind,
muss F neu berechnet werden, sonst wird F einfach mit U überschrieben (Zeile 77
und 80).
Wie in Kapitel 3.2.4 auf Seite 46 beschrieben wird jetzt der diskretisierte F-Term der
∂u 2
∂uv
Impulsgleichung berechnet. Die beiden konvektiven Terme
und
werden in
∂y
∂x
den Zeilen 84 – 97 und 100 – 113 berechnet. Die Diffusion wird in den Zeilen 118 –
122 bestimmt und abschließend wird alles in Zeile 125 zusammenaddiert und zurückgegeben.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 69 von 99
3.4.6. Visualisierung
Die Lösung der Navier-Stokes-Gleichungen liegt nun zum Zeitpunkt n+1 vor. Zur Visualisierung stehen insgesamt fünf verschiedene Ansichten bereit:
Geschwindigkeitsfeld: Zeigt eine Farbkodierung der Richtungsvektoren
Partikel: Zeigt Bahnlinien von Partikel, die in die Strömung ausgesetzt werden
Hindernisse: Zeigt die Hindernisse im Gebiet Ω an, um sie zu editieren
Druck: Zeigt die aktuelle Druckverteilung an
Rotation: Stellt die Verteilung der Wirbelstärke dar
Geschwindigkeitsfeld
Als Visualisierungstechnik kommt für das Geschwindigkeitsfeld eine einfache Farbkodierung der Richtungsvektoren zum Einsatz.
Im roten Farbanteil wird die x-Komponente und im grünen Anteil die y-Komponente
eines Vektors dargestellt. Dabei wird der Nullvektor in die Mitte der beiden Farbanteile gelegt, da die Werte positiv und negativ werden können. Mit einem Rot- und Grünanteil von 0.5 wird der Nullvektor repräsentiert. Je länger der Vektor, desto weiter
zeigt er an den Rand des Quadrats.
Abbildung 33: Farbkodierung der Richtungsvektoren
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 70 von 99
Für den Nullvektor ergibt sich grünliches Gelbbraun. Vektoren nach rechts werden
durch orange Farbe gekennzeichnet, Vektoren nach links unten durch Grün und Vektoren nach links oben durch Schwarz.
Abbildung 34: Einströmung von links nach rechts mit Wirbelbildung
Im Demoprogramm gibt es die Möglichkeit die Vektoren vor der Darstellung normalisieren zu lassen. Hier sieht man an den Stellen, wo alle Farben in einer Singularität
zusammentreffen, die Wirbelzentren.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 71 von 99
Partikelverfolgung
Eine andere Möglichkeit die Strömung sichtbar zu machen ist die Partikelverfolgung.
Hier werden einzelne Partikel an eine bestimmte Stelle im Gebiet Ω eingesetzt und
durch die Strömung fort getragen. Es werden nicht nur einzelne Partikel betrachtet,
sondern eine Partikelverteilung, die an jeder Stelle im Gebiet Ω eine bestimmte Intensität hat.
In der Demo können diese Partikel einfach mit der linken Maustaste eingesetzt werden. Mit dem Mausrad kann die Größe des Radius verändert werden in dem neue
Partikel hinzugefügt werden. So können auf einmal sehr viele oder sehr wenige neue
Partikel eingesetzt werden.
Sei p ∈ Ω die zweidimensionale Position eines einzelnen Partikels im Gebiet Ω. Pro
Zeitschritt wird die Gitterzelle (i, j ) bestimmt, in der p liegt. Dazu wird im einfachsten
Fall (i, j ) = ( p x / δx, p y / δy ) berechnet, wobei δx und δy die Zellenabmaße sind. Eine
bilineare Interpolation zu den umliegenden vier Gitterzellen kann verwendet werden
um genauere Ergebnisse zu erzielen. Die Gitterzelle (i, j ) wird benötigt um den entu 
sprechenden Geschwindigkeitsvektor UVi , j =   ausgelesen.
 v i, j
In einer Vorwärtsverfolgung wird UVi,j auf die Position p addieren, um die neue Position des Partikels im nächsten Zeitschritt zu bestimmmen. Aus technischen Gründen
ist die Vorwärtsverfolgung auf der Grafikkarte nicht mit vernünftiger Performance berechenbar, so dass eine Rückwärtsverfolgung implementiert wurde.
In der Rückwärtsverfolgung wird ausgehend von der aktuellen Zelle (i, j ) der Geschwindigkeitsvektors in umgekehrter Richtung –UVi,j verfolgt und die Zelle (i ' , j ')
bestimmt, auf die (i ' , j ') = (i − ui , j − v j ) zeigt. Auch hier kann wieder eine bilineare Interpolation angewendet werden um genauere Ergebnisse zu erhalten. Die an Stelle
(i' , j ') gefundenen Partikel werden in die Zelle (i, j ) kopiert. Die Rückwärtsverfolgung
ist wesentlich ungenauer als die Vorwärtsverfolgung, da ja auch mehrere Geschwindigkeitsvektoren in die gleiche Zielzelle zeigen könnten. Dieser Fall wird nicht berücksichtigt, dafür ist die Berechnung sehr schnell.
Zusätzlich zur Verfolgung diffundieren die Partikel. Die Diffusionsrate kann im Einstellungsdialog des Programms festgelegt werden. Mathematisch funktioniert die Diffusion genauso, wie sie bei der Impulsgleichung beschrieben worden ist. So breiten
sich je nach Diffusionsrate die Partikel unabhängig von der Strömung aus.
Die Partikel werden in der Standardeinstellung des Programms durch Grauwerte visualisiert, die von der jeweiligen Intensität an jeder Stelle abhängen. Je mehr Intensität an einem Ort vorliegt, desto weißer wird dieser Bereich dargestellt. Je weniger,
desto dunkler wird die Darstellung.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 72 von 99
Abbildung 35: Partikelverfolgung
Um verschiedene Materialien zu simulieren, können die Partikel eingefärbt werden.
Dazu werden eindimensionale Paletten verwendet, die auf zwei Arten indiziert werden können:
Intensitätsindizierung: Der Index in die Paletten ist die Partikelintensität. Diese
Indizierung eignet sich für Materialien, die in dichterem Zustand anderes Licht
aussenden, als im undichteren Zustand. Wie in Abbildung 36 zeigt, kann damit zum Beispiel Feuer dargestellt werden. Im dichtesten Zustand weiß, ändert es mit Abnahme der Intensität seine Farbe zu gelb über rot nach
schwarz.
Abbildung 36: Partikel mit Feuerpalette
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 73 von 99
Indizierung über die Partikelposition: Die y-Komponente der Partikelposition
wird als Index in die Palette verwendet. Damit können statische Farbverläufe
von Medien simuliert werden.
Beide Indizierungsarten können im Demoprogramm parallel angewendet werden, wie
es in Abbildung 37 dargestellt ist.
Abbildung 37: Intensitätspalette und Positionspalette
Neben dem Einfügen von Partikeln mit der linken Maustaste, kann ein Pinsel bzw.
Stempel aus einer Grafikdatei geladen werden. An jedem Punkt der Grafik wird der
Mittelwert über die drei Farbkomponenten Rot, Grün und Blau zu einer Graustufe
gemittelt. Mit gedrückter Shift-Taste und einem Klick auf die linke Maustaste, wird
dieses Graubild als Partikelpinsel an der Mausposition eingefügt. Im Bild unten wurde das tum3D Logo als Partikelpinsel verwendet.
Abbildung 38: Partikelpinsel
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 74 von 99
Druck
Da die Druckwerte positiv und negativ werden können, wird die gleiche Visualisierungstechnik wie beim Geschwindigkeitsfeld angewandt, mit dem Unterschied, dass
hier nur eine Dimension benötigt wird. Ein Druck von Null wird mit 0.5 im Rotkanal
kodiert, also ein mittelhelles Rot. Großer positiver Druck wird als helles Rot dargestellt, großer negativer Druck als Dunkelrot bis Schwarz.
Abbildung 39: Beispiel einer Druckverteilung
Rotation (Wirbelstärke)
Diese Darstellung stellt die Wirbel im Geschwindigkeitsfeld dar. Dazu werden lila
Farben benutzt, die die Stärke und Richtung der Wirbel visualisiert. Wie beim Druck
werden positive und negative Wirbelstärke durch helles Lila bzw. Schwarz dargestellt, während Wirbelfreiheit durch einen Mittelwert angezeigt wird.
Die Wirbelstärke ζ kann direkt aus einem gegebenen Geschwindigkeitsfeld berechnet werden.
ζ (x, y ) :=
∂u ∂v
−
∂y ∂x
Nach der Diskretisierung ergibt sich folgende Formel.
ζ (i, j ) :=
ui , j +1 − ui , j
δy
−
vi +1, j − vi , j
δx
Die Berechnung von ζ erfolgt nur, falls die entsprechend Ansicht auch ausgewählt ist.
Abbildung 40: Rotation der Wirbelstrasse
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 75 von 99
Hinderniseditor
Die Hindernisse werden als blaue Pixel dargestellt. Mit der linken Maustaste können
neue Hinderniszellen hinzugefügt werden und mit der rechten Maustaste wieder entfernt werden. Wie bei der Partikelverfolgung kann hier mit dem Mausrad die Größe
des Pinsels verändert werden.
Da der Hinderniseditor neben den diesen elementaren Einfüge- und Löschoperationen keine weitere Funktionalität bietet, wurde eine Import-Funktion implementiert, mit
der man beliebige Bilder als Hinderniskarte einlesen kann. Das Bild muss dabei in
einem der folgenden Formate vorliegen:
JPEG (*.jpg)
Portable Network Graphics (*.png)
Truevision Targa (*.tga)
Windows Bitmap (*.bmp)
Um aus beliebigen Bildern eine gültige Hindernistextur zu erzeugen, werden alle sehr
dunklen bis schwarzen Pixel ignoriert. D.h. hier bleiben die Fluidzellen erhalten, wohingegen die farbigen Bereiche des Bildes als Hinderniszellen interpretiert werden.
Falls sich beim Setzen von neuen Hindernissen ungültige Hinderniszellen ergeben
(siehe Kapitel 3.2.2 auf Seite 44), werden diese als weiße Punkte dargestellt. Durch
erneutes Hinzufügen oder Entfernen von Hinderniszellen müssen die ungültigen Zellen unbedingt beseitigt werden, da sonst die Simulation nicht funktioniert.
Abbildung 41: Hindernisse mit ungültigen Zellen
Overlay Texturen
Um die optische Qualität zu steigern, können beliebige Bilder als Overlay Texturen
geladen werden, die über jede Ansicht gelegt werden. So können beispielsweise die
blauen Hinderniszellen mit einem farbigen Bild überklebt werden, um den optischen
Eindruck zu verbessern.
Overlay Texturen müssen nicht von der gleichen Größe sein wie das diskretisierte
Gebiet. Durch scharfe Overlay Texturen werden die kantigen Ränder an Hinderniszellen zu glatten Rändern, wie es in Abbildung 42 zu sehen ist.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 76 von 99
Abbildung 42: Overlay Texturen
3.4.7. Geschwindigkeitsmessungen
Die Rechengeschwindigkeit wurde auf einem System mit AMD Athlon 1,2 GHz Prozessor und einer ATI Radeon 9700 Pro gemessen. Als Betriebssystem kam wieder
Windows XP Professional zum Einsatz. Wie schon bei den Geschwindigkeitsmessungen des Wasserprogramms aus Kapitel 2, wurde das Programm mit verschiedenen Parameterkombinationen gemessen.
Neben der Abhängigkeit von der Bildschirmauflösung, spielt diesmal auch die gerade
ausgewählte Visualisierungstechnik eine entscheidende Rolle für die Geschwindigkeit. Da die Visualisierung als eigener Software-Layer realisiert wurde, kann man die
benötigte Rechenzeit in zwei Komponenten aufteilen.
Zum einen benötigt die eigentliche Berechnung der Navier-Stokes-Gleichungen einen festen Rechenaufwand, der im Wesentlichen nur von der Anzahl der Gitterzellen
abhängt. Dies allerdings der Hauptfaktor in der gesamten Leistungsbilanz.
Zum anderen benötigt jede Visualisierungstechnik unterschiedlich viel zusätzliche
Rechenzeit. In der folgenden Auflistung sind die Visualisierungstechniken nach ihrem
Leistungsbedarf in absteigender Reihenfolge sortiert. Jeweils in Klammern daneben
ist der entsprechende Geschwindigkeitsfaktor in Bezug auf die schnellste Visualisierungstechnik, die Darstellung des Drucks, angegeben.
1.
2.
3.
4.
5.
Druck
Hinderniseditor
Partikel
Wirbelstärke
Geschwindigkeitsfeld
( 100 % )
( 98 % )
( 97 % )
( 76 % )
( 66 % )
Die obigen Geschwindigkeitsfaktoren wurden auf einem Gitter von 128 mal 128 Zellen bei einer Bildschirmauflösung von 1024 mal 768 Bildpunkten gemacht. Es wurde
immer die Gesamtleistung betrachtet, also inklusive Berechnung der Navier-StokesGleichungen und nicht nur die Visualisierungstechnik alleine.
Bei anderen Gitterauflösungen und anderen Bildschirmauflösungen ergeben sich
andere Faktoren, aber die Reihenfolge bleibt immer gleich.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 77 von 99
Die Visualisierung des Geschwindigkeitsfeldes benötigt deshalb so viel Rechenzeit,
weil in jedem Punkt auf dem Bildschirm eine bilineare Interpolation auf dem Geschwindigkeitsfeld durchgeführt wird. Deswegen ist diese Visualisierung stark von
der gewählten Bildschirmauflösung abhängig.
Die Wirbelstärke wird während der Berechnung der Navier-Stokes-Gleichungen nicht
explizit bestimmt, sondern erst in der Visualisierungsschicht. Deswegen ist diese
Darstellung verhältnismäßig langsam.
Partikel-, Hindernis- und Druckvisualisierung sind deswegen so schnell, weil nichts
weiter berechnet werden muss. Aus den entsprechenden Texturen werden lediglich
die notwendigen Texel ausgelesen und in den Bildschirmspeicher kopiert.
Nach dieser Erläuterung zur Visualisierungsschicht folgen nun konkrete Messungen
der Bilder pro Sekunde bzw. Frames per Second unter verschiedenen Gitterauflösungen und Bildschirmauflösungen. Es wurde jeweils eine Tabelle pro Visualisierungstechnik erstellt. Da sich die Bilder pro Sekunde bei der Visualisierung von Partikeln, Hindernissen und Druck nur sehr gering unterscheiden, wurde hier auf separate
Diagramme verzichtet.
Geschwindigkeitsfeld
Bilder pro Sekunde
80
70
60
50
640x480
40
800x600
30
1024x768
20
10
0
64
128
256
Gittergröße
Abbildung 43: Geschwindigkeit bei Visualisierung des Geschwindigkeitsfelds
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 78 von 99
Bilder pro Sekunde
Wirbelstärke
90
80
70
60
50
40
30
20
10
0
640x480
800x600
1024x768
64
128
256
Gittergröße
Abbildung 44: Geschwindigkeit bei Visualisierung der Wirbelstärke
Bilder pro Sekunde
Partikel, Hinderniseditor, Druck
100
90
80
70
60
50
40
30
20
10
0
640x480
800x600
1024x768
64
128
256
Gittergröße
Abbildung 45: Geschwindigkeit von Partikeln, Druck oder Hindernissen
Um die Abhängigkeit von der Bildschirmauflösung zu lösen, kann jede Ansicht zuerst
in eine Zwischentextur visualisiert werden, die die gleiche Auflösung wie das diskretisierte Gebiet hat. Diese Textur wird anschließend auf den Bildschirm gezeichnet. Bei
steilen Änderungen in den Partikelpaletten entstehen mit dieser Methode Artefakte,
auf der anderen Seite bringt es manchmal eine Performacesteigerung von bis zu
10%.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 79 von 99
3.5. Simulierte Probleme
3.5.1. Nischenströmung
Als Nischenströmung bezeichnet man das Strömungsverhalten, wenn ein geradliniger Strom über eine Nische bzw. Ausbuchtung fließt. In der Realität kommt dieses
Phänomen zum Beispiel bei einem Bach vor, der über eine Bodenunebenheit fließt.
Folgende Abbildung stellt das Problem anschaulich dar.
Abbildung 46: Nischenströmung
In der Demo wird nur die Nische selbst simuliert, nicht der Strom, der darüber fließt.
Als Bedingungen für den linken, rechten und unteren Rand werden Haftbedingungen
gesetzt und zur Simulation des Flusses am oberen Rand eine so genannte Bandbedingung (Driven Cavity). Dazu wird ein Einheitsvektor nach rechts gesetzt.
Das Gebiet kann quadratisch sein, muss es aber nicht. Zusätzliche Hindernisse können ebenfalls eingefügt werden, um die Nische mit einer realistischeren Kontur zu
versehen. Als Anfangsbedingung für die Geschwindigkeit und den Druck innerhalb
der Nische wird jeweils Null gewählt. So ist das gesamte Gebiet anfangs in Ruhe, bis
auf die Bandbedingung am oberen Rand.
Die Verwirbelung, die in der Nische entsteht, hängt von der Reynoldszahl des Fluids
ab. Je größer sie wird, desto weiter verschiebt sich der Wirbel in die rechte obere
Ecke, und es bildet sich nach einiger Zeit ein weiterer Wirbel in der linken unteren
Ecke der Nische. Bei kleineren Reynoldszahlen bleibt das untere Drittel der Nische
immer in Ruhe und es bilden sich keine weiteren Wirbel.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 80 von 99
Abbildung 47: Vektorfeld einer Nischenströmung mit hoher Reynoldszahl
Abbildung 48: Partikelverfolgung in der Nischenströmung
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 81 von 99
3.5.2. Kármánsche Wirbelstraße
Die Kármánsche Wirbelstraße ist die Simulation, die man in jedem Buch über Strömungsmechanik findet. Hier wird ein von linken Seite einströmendes Fluid simuliert,
das auf ein Hindernis, wie zum Beispiel einen Balken, trifft. Mit hoher Reynoldszahl
(Re ≈ 10000) entstehen hinter dem Hindernis Verwirbelungen, die man als
Kármánsche Wirbelstraße bezeichnet.
Abbildung 49: Kármánsche Wirbelstraße
Die Breite des Gebiets wurde in dieser Simulation vier Mal so groß gewählt wie die
Höhe. Als Einströmungsbedingung am linken Rand nimmt man wiederum einen Einheitsvektor, der nach rechts zeigt. Am oberen und unteren Rand, sowie am unteren
Rand wählt man ebenfalls einen Einheitsvektor mit der gleichen Richtung wie am
linken Rand. Diese Art von Randbedingung nennt man auch Ozeanbedingung, weil
dadurch ein unendliches Feld simuliert wird.
Als Besonderheit sei darauf hingewiesen, dass der Initialvektor für das Geschwindigkeitsfeld UV0 auch ein Einheitsvektor nach rechts sein muss, damit die Simulation
funktioniert. Mit anderen Worten: Es muss das gesamte Gebiet inklusive Rand mit
dem Initialvektor UV0 belegt werden, der kein Nullvektor sein darf.
Die nachfolgende Abbildung zeigt das Geschwindigkeitsfeld in der Kármánsche Wirbelstraße. Bei der Simulation über einen schrägen Balken bilden sich sofort Verwirbelungen. Die Strömung ist über die Zeit periodisch.
Abbildung 50: Strömung über einen schrägen Balken mit hoher Reynoldszahl
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 82 von 99
Wenn man in dieses Geschwindigkeitsfeld Partikel injiziert, dann kommt folgendes
Bild zustande.
Abbildung 51: Partikelverfolgung über den schrägen Balken
Hier wurden die Partikel gelb eingefärbt, und eine Overlay Texture verwendet, die in
der rechten unteren Ecke das tum3D-Logo einblendet. Dieses Logo ist im Gegensatz
zu dem Balken kein Hindernis.
Wählt man als Hindernis statt des schrägen Balkens einen Kreis, so bildet sich die
Wirbelstraße nicht sofort aus. Bei kleinen Reynoldszahlen schließen sich die Stromlinien hinter dem Hindernis gleich wieder, ohne dass es zu Verwirbelungen kommt.
Bei hohen Reynoldszahlen bildet sich hinter dem Hindernis zunächst ein Rückstrom,
von dem sich erst nach einiger Zeit Wirbel ablösen und davon treiben.
Abbildung 52: Simulation eines Flusses (Partikelverfolgung)
Abbildung 52 zeigt die Simulation eines Flusses, der sich um verschiedene Steine
herumschlängelt. Hierzu wurden die Partikel bläulich eingefärbt und als Hindernisund Overlay-Textur eine Fläche mit ein paar Steinen verwendet. Hinter jedem kleinen
Steine bildet sich eine kleine Kármánsche Wirbelstraße. Das zugehörige Geschwindigkeitsfeld ist in Abbildung 53 dargestellt.
Abbildung 53: Simulation eines Flusses (Geschwindigkeitsfeld)
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 83 von 99
3.5.3. Stufenströmung
Bei der Stufenströmung befindet sich in der linken unteren Ecke ein Hindernis und
darüber strömt das Fluid mit dem Initalvektor UV0 ein. Für UV0 wurde ein
Einheitsvektor nach rechts gewählt. Wie schon bei der Kármánsche Wirbelstraße
werden auch hier an allen Rändern die Ozeanrandbedingung gesetzt.
Abbildung 54: Strömung über eine Stufe
Die Gebietsgröße kann für diese Simulation beliebig gewählt werden. In der hier vorgestellten Simulation wurde ein Breiten-Höhen-Verhältnis von zwei zu eins mit 128
mal 64 Gitterzellen verwendet.
Je größer die Reynoldszahl ist, desto lang gestreckter wird der Wirbel, der sich
rechts hinter der Stufe bildet. Je kleiner sie ist, desto näher bleibt der Wirbel an der
Schwelle.
In den folgenden Abbildungen wurde als Overlay Texture ein natürlicher Felsen eingezeichnet um so einen Wasserfall zu simulieren. Dementsprechend wurden die Partikel blau gefärbt um Wasser darzustellen.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 84 von 99
Abbildung 55: Stufenströmung mit Re = 1000 (Geschwindigkeitsfeld)
Die obige Abbildung wurde mit einer Reynoldszahl von 1000 berechnet. An den gelben Bereichen kann man erkennen, wie die Strömung nach rechts unten zeigt. In
den grünen Bereichen am unteren Bildrand erkennt man den Rückstrom nach rechts.
Abbildung 56 zeigt die Partikelverfolgung im Wasserfall.
Abbildung 56: Stufenströmung mit Re = 1000 (Partikelverfolgung)
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 85 von 99
3.5.4. Strömung über ein Auto
Bei der Fahrzeugentwicklung sind Tests der Windschnittigkeit neuer Autos sehr wichtig. Der Treibstoffverbrauch hängt direkt mit dem Luftwiderstand des Fahrzeugs zusammen. Um diese Tests durchzuführen, werden Prototypen oder kleinere Modelle
in Windkanäle gestellt und von Luft aus Windmaschinen umströmt. In praktischen
Experimenten werden Rauch- oder Staubpartikel in die Strömung injiziert um die
Strömung sichtbar zu machen.
Mit Hilfe der Navier-Stokes-Gleichungen können Windkanale durch Simulationen am
Computer ersetzt werden.
Für dieses Anwendungsbeispiel wird ein Gebiet wie bei der Kármánsche Wirbelstraße erzeugt (siehe Seite 81): Die Initialvektoren UV0 werden auf den Einheitsvektor
nach rechts gesetzt, an den Ränder herrscht eine Ozeanrandbedingung und die
Reynoldszahl wird auf 10000 gesetzt. Als Overlay Textur wurde die Seitenansicht
eines Autos über die Hindernisse gelegt (Quelle [21]).
Abbildung 57: Auto im Windkanal (Geschwindigkeitsfeld)
An der Motorhaube und Windschutzscheibe ist durch die rote Farbe ersichtlich, wie
sich die Vektoren den Weg über das Auto bahnen. Hinter dem Auto entstehen starke
Verwirbelungen.
Bei diesen Simulationen geht es immer um die relative Geschwindigkeit zwischen
Fluid und Hindernis. D.h. es ist egal, ob das Auto steht und Wind auf das Auto bläst,
oder ob das Auto in Fahrt und die Luft in Ruhe ist: Das Strömungsbild ist in beiden
Fällen identisch.
Abbildung 58: Auto im Windkanal (Geschwindigkeitsfeld)
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 86 von 99
3.5.5. tum3D-Logo
In der letzten Simulation geht nicht um eine wissenschaftliche Simulation, sondern
um Strömung um das Logo des Lehrstuhls.
Hier wurde ein Gebiet mit 128 mal 128 Gitterzellen und einem Initialvektor UV0 nach
oben definiert. Als Hindernis und Overlay Textur wurde das tum3D Logo in die Mitte
des Gebiets gesetzt. Die Partikel wurden mit einer Feuerpalette eingefärbt.
Abbildung 59: tum3D-Logo (Geschwindigkeitsfeld)
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 87 von 99
3.6. Erweiterungen
In diesem Abschnitt werden mögliche Erweiterungen zu der bisher vorgestellten Simulation aufgezeigt. Neben weiteren Visualisierungstechniken können auch physikalische Phänomene wie die Temperatur berechnet werden. Die Simulation von Fluiden, die sich erst in ein Gebiet ausbreiten, bezeichnet man als freie Randwertprobleme. Im Abschnitt zu numerischen Fehlern geht es um die Minimierung der Rechenfehler. Abschließend wird eine Erweiterung der Navier-Stokes-Gleichungen ins DreiDimensionale vorgestellt.
3.6.1. Visualisierung
Die Farbkodierung der Geschwindigkeitsvektoren ist nicht besonders intuitiv verständlich. Die Partikelverfolgung gibt dem Betrachter einen wesentlich besseren Eindruck, wie die Strömungsverhältnisse sind.
Eine bessere Visualisierungstechnik wären zum Beispiel kleine Pfeile, die in die
Richtung des Vektors zeigen und durch ihre Länge die Vektorlänge wiedergeben.
Mit einer Exportfunktion für Geschwindigkeitsfelder könnte man sie in anderen Visualisierungstools wie AVS anzeigen und nachbearbeiten.
Andersherum könnten gegebene Geschwindigkeitsfelder durch eine Importfunktion
weiter simuliert werden.
Für den Druck und die Rotation könnten Isolinien die Anschaulichkeit steigern.
3.6.2. Stromfunktion
Neben der Wirbelstärke (siehe Kapitel 3.4.6 auf Seite 69) kann auch die Stromfunktion ψ berechnet werden, die die Stromlinien des Geschwindigkeitsfeldes mit
ψ ( x, y ) = const bestimmt. Im Kontinuierlichen ist sie wie folgt definiert:
∂ψ ( x, y )
:= −v,
∂x
∂ψ ( x, y )
:= u
∂y
In der Diskretisierung ergibt sich eine Startzeile
ψ i ,0 = ψ i −1,0 − vi , 0δx,
i = 1,..., imax
und eine Formel für den Rest des Gebiets
ψ i , j = ψ i , j −1 − ui , j δy,
i = 1,..., imax ,
j = 1,..., jmax
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 88 von 99
Wie aus letzter Formel ersichtlich, kommt man mit dieser Formel in ähnliche Probleme wie bei der Berechnung des Gauss-Seidel-Verfahrens. Das ψi,j benötigt den bereits aktualisierten Wert ψi,j-1 und das ist technisch auf der Grafikhardware nicht möglich. Hier müsste man erst nach neuen Wegen suchen, um die Stromfunktion zu berechnen.
3.6.3. Hinderniseditor
Der Hinderniseditor ist sehr rudimentär gehalten. Er unterstützt nur die wesentlichen
Funktionen um Hinderniszellen einzufügen und zu löschen.
In einem komfortablen Hinderniseditor sollte auch die Pinselform wählbar sein, wie
zum Bespiel Rechtecke. Außerdem wären einfache Zeichenfunktionen sehr nützlich:
Funktionen, mit der man Linien ziehen kann oder Füllfunktion, mit der Bereich mit
leeren bzw. Hinderniszellen ausgefüllt werden können.
3.6.4. Numerische Fehler
Auf Grund der begrenzten Anzahl von Instruktionen im Pixel-Shader, wurden die
meisten Shader auf Speicherplatz optimiert, damit so wenige Rendering-Passes benötigt werden wie möglich. Dieses Vorgehen begünstigt numerische Fehler, die
durch eine bestimmte Reihenfolge der mathematischen Operationen verursacht werden.
Die Rechenfehler resultieren zum einen aus der begrenzten Bitbreite eines Fließkommawortes. Reelle Zahlen sind unendlich genau, aber das lässt sich im Rechner
nicht darstellen und deshalb müssen sie ab einer bestimmten Stelle abgeschnitten
werden. Bei der mathematischen Operation mit zwei Zahlen, bei der eine sehr klein
und die andere sehr groß ist, können sich Auslöschungen von Bits und damit große
Rechenfehler ergeben.
Als illustrierendes Beispiel sei auf den Code aus Kapitel 3.4.5 auf Seite 64 verwiesen. Bei der Berechnung des diffusiven Anteils wird ein so genannter Stern ausgewertet:
118
119
120
float wave = Re *
((centerright.x - 2*center.x + centerleft.x) * rdx2 +
(bottomcenter.x - 2*center.x + topcenter.x ) * rdy2);
Diese Berechnung ist numerisch fehlerfrei, wenn man sie folgendermaßen ausdrückt:
118
119
120
121
122
float wave = Re *
((centerright.x
centerleft.x
(bottomcenter.x
topcenter.x
-
center.x +
center.x) * rdx2 +
center.x +
center.x) * rdy2);
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 89 von 99
In der unteren Version bleiben alle beteiligten Zwischenergebnisse immer in etwa
gleich groß. Das ist eine wesentliche Vorraussetzung um Auslöschungen von Bits in
Fließkommazahlen zu vermeiden.
Hier sei auf einschlägige Literatur zur Numerik auf Computern hingewiesen, die sich
umfassend mit dieser Thematik befasst.
Wenn die Länge der Shader-Programme im Pixel-Shader 3.0 Standard nicht mehr
auf 64 Befehle beschränkt ist, sollte man nicht nur zusammengehörige ShaderProgramme zusammenfassen, sondern auch die mathematischen Operationen auf
numerische Korrektheit überprüfen.
3.6.5. Freie Randwertprobleme
Mit freien Randwerten definiert man noch eine weitere Unterscheidung zwischen
verschiedenen Zelltypen. Bisher gab es entweder Fluidzellen oder Hinderniszellen.
Hier kommt noch eine dritte hinzu: eine leere Zelle.
Fluide können sich nun in leere Zellen ausbreiten bzw. Zellen verlassen. Damit lassen sich dann zum Beispiel Wassertropfen, die in ein Becken fallen simulieren.
Die Ausbreitung eines Fluids wird mit Hilfe eines Partikelverfolgers realisiert. In jede
Zelle des Gitters, in der sich anfangs das Fluid befinden soll, wird eine feste Menge
an Partikeln gesetzt. In der Praxis sind das meist 9 oder 16 Partikel. Zu Beginn des
Algorithmus werden diese Partikel mit der Partikelverfolgung auf dem aktuellen Geschwindigkeitsfeld bewegt. Dadurch gelangen einige der Partikel in Zellen, in denen
vorher noch kein Fluid war, und umgekehrt kann eine Zelle leer werden, wenn sie
alle Partikel verlassen haben.
Die Partikel zeigen jetzt an, in welchen Zellen Fluid ist und in welchen nicht. Jetzt
kann der so genannte Freirand bestimmt werden. Das sind die Fluidzellen, die an
eine oder mehrere leere Zellen angrenzen. An diesem Freirand müssen wieder für
die Geschwindigkeitsfelder UV und FG sowie für den Druck Randwerte gesetzt werden. Nun wird die Impulsgleichung in den Fluidzellen wie gehabt ausgewertet und die
Schleife beginnt von vorne mit der Partikelverfolgung.
3.6.6. Temperatur (Energietransport)
In vielen technischen Anwendungen ist bei der Simulation von Strömungen die Temperatur ein wichtiger Faktor. Man denke beispielsweise an die Wettervorhersage, wo
Wolkenströmungen entscheidend durch die Temperatur beeinflusst werden.
Jedes Fluid besitzt thermodynamische Eigenschaften. Die Temperatur eines Fluids
wirkt sich auf die Dichte des Mediums aus. Durch Erwärmung dehnt sich das Fluid
aus, und es steigt auf, weil es leichter wird. So entstehen thermische Auftriebskräfte,
die sich auf das Geschwindigkeitsfeld auswirken.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 90 von 99
Die Temperatur korrekt in die Gleichung einzubeziehen ist unter exakten Bedingungen äußerst schwierig, weshalb man sich auf eine Approximation beschränken kann;
zum Beispiel die Boussinesq-Appromixation.
Dabei wird als Vereinfachung angenommen, dass die Dichte im Fluid konstant ist,
außer bei den Termen der Auftriebskräfte. Dadurch können die inkompressiblen Navier-Stokes-Gleichungen beibehalten werden. Sie werden lediglich durch die Terme
der Auftriebskräfte erweitert.
Ein interessantes Beispiel ist das Heizen einer Wand: In dem rechteckigen Gebiet Ω
wird ein ruhendes Fluid gesetzt mit UV = 0. Durch das Heizen einer der vier Seitenwände beginnt nun das Fluid in Bewegung zu geraten. So entsteht ein Wirbel im Gebiet.
3.6.7. Dreidimensionale Navier-Stokes-Gleichungen
Wegen der nicht ausreichenden Rechenkraft ist es heute zwar noch nicht möglich die
Navier-Stokes-Gleichungen im Dreidimensionalen in Echtzeit zu berechnen, aber in
den kommenden Jahren dürfte auch das durchführbar werden. Erst in der dreidimensionalen Simulation lassen sich die meisten Naturphänomene realistisch nachrechnen, wie zum Beispiel der Luftstrom um ein Auto im Windkanal.
Neben der aufwändigen Berechnung der Navier-Stokes-Gleichungen, müssen hier
auch aufwändigere Visualisierungstechniken verwendet werden. Um ein dreidimensionales Strömungsvolumen darzustellen, braucht man einen Volumenrenderer. Alternativ können auch nur einzelne Scheiben des Volumens betrachtet werden, allerdings ist diese Darstellung nicht besonders anschaulich.
Im Dreidimensionalen ergeben sich drei Impulsgleichungen in dimensionsloser Darstellung.
( )
∂u ∂p 1  ∂ 2 u ∂ 2 u ∂ 2 u  ∂ u 2 ∂(uv ) ∂ (uw)

−
+
=
+
+
−
−
+ gx
∂t ∂x Re  ∂x 2 ∂y 2 ∂z 2  ∂x
∂y
∂z
( )
∂v ∂p 1  ∂ 2 v ∂ 2 v ∂ 2 v  ∂ (uv ) ∂ v 2 ∂ (vw)

−
+
=
+
+
−
−
+ gy
∂t ∂y Re  ∂x 2 ∂y 2 ∂z 2 
∂x
∂y
∂z
( )
∂w ∂p 1  ∂ 2 w ∂ 2 w ∂ 2 w  ∂ (uw) ∂ (vw) ∂ w 2

−
+
=
+
+
−
−
+ gz
∂t ∂z Re  ∂x 2 ∂y 2 ∂z 2 
∂x
∂y
∂z
Dementsprechend ergibt sich folgende Kontinuitätsgleichung:
∂u ∂v ∂w
+ +
=0
∂x ∂y ∂z
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 91 von 99
Die Variable w bezeichnet hierbei die Geschwindigkeitskomponente in Richtung der
z-Achse.
Die Behandlung der Ränder muss auf die Seitenflächen des Volumens übertragen
werden, wobei prinzipiell die gleichen Bedingungen wie im zweidimensionale Fall
verwendet werden: Haft-, Rutsch-, Einström- und Ausströmbedingung. Das gilt auch
für Hindernisse im Raum, bei denen jetzt noch mehr Fallunterscheidungen für die
Nachbarschaftsbeziehungen abgearbeitet werden müssen.
Die Diskretisierung erfolgt analog zum zweidimensionalen Fall, allerdings um eine
Komponente erweitert. Statt nur die F-G-Terme zu berechnen müssen hier die
F-G-H-Terme ausgewertet werden, die folgendermaßen aussehen:
δt (n+1)
(δp )
δx
δt
v (n+1) = G (n ) − (δp (n+1) )
δy
δt
w (n+1) = H (n ) − (δp (n+1) )
δz
u (n+1) = F (n ) −
Zur Berechnung des Drucks ergibt sich im Dreidimensionalen folgende PoissonGleichung:
∂ 2 p (n+1) ∂ 2 p (n +1) ∂ 2 p (n+1) 1  ∂F (n ) ∂G (n ) ∂H (n ) 

+
+
= 
+
+
∂y
∂z 
∂t  ∂x
∂x 2
∂y 2
∂z 2
Dies sollte nur eine Idee geben, wie die dreidimensionalen Navier-StokesGleichungen aussehen. Für weitere Informationen siehe [6].
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 92 von 99
4. Fazit
Die beiden Teilprojekte Simulation von Wasseroberflächen und Simulation von Fluiden haben gezeigt, dass moderne Grafikhardware eine Alternative zu teuren Rechenanlagen sein kann, um aufwändige Simulation zu berechnen. Gerade durch die
sehr schnelle Weiterentwicklung der Grafikkarten ist in Zukunft noch sehr viel Potential in diesem Forschungszweig.
Während vor ein paar Jahren Grafikkarten nicht viel mehr als Dreiecke mit Texturen
überziehen und beleuchten konnten, hat sich die neue Generation der Chips von ihrem Dasein als Spezialbaustein für ein bestimmtes Anwendungsgebiet zu GeneralPurpose-Bausteinen entwickelt.
Auch wenn es Algorithmen gibt, die sich gar nicht oder nur sehr schlecht auf die Grafikkarte portieren lassen, ist eine Vielzahl von Problemen auf Grafikhardware schneller zu berechnen als auf herkömmlichen CPUs. Gerade Operationen auf Vektoren
und Matrizen sind ein Spezialgebiet der GPUs. Mit Pixel-Shader Programmen sind
Berechnungen mit Arrays sehr schnell durchführbar.
Mit der Unterstützung der Pixel-Shader 3.0 und Vertex-Shader 3.0 Standards in
Hardware ist die nächste große Evolutionsstufe schon absehbar. Die Instruktionssets
werden vereinheitlicht, Längenbeschränkungen der Programme werden über 65536
Befehle verschoben und echte Sprünge werden möglich. Damit können dann auch
Schleifen aller Art programmiert werden. Diese Generation der Grafikkarten wird völlig neue Anwendungsgebiete für GPUs eröffnen.
Wie man im Erweiterungen auf Seite 87 lesen kann, gibt es noch zahlreiche Dinge,
um die man die beiden Projekte erweitern kann.
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 93 von 99
Literaturverzeichnis
[1]
Deloura Mark A., "Game Programming Gems 1", Charles River Media, Inc,
2000, Hingham Massachusetts, ISBN 1-58450-049-2
"Fractal Terrain Generation - Midpoint displacement", Jason Shankel,
S. 503 – 507
"Improved Environment-mapped reflection using glossy prefiltering and
the fresnel term", Anis Ahmad, S. 581 – 585
"Refraction mapping for liquids in containers", Alex Vlachos and Jason
L. Mitchell, S. 594 – 599
[2]
Treflia Dante, "Game Programming Gems 3", Charles River Media, Inc,
2002, Hingham Massachusetts, ISBN 1-58450-233-9
"Fast Heightfield Normal Calculation", Jason Shankel, S. 344 – 348
“Interactive Simulation of Water Surfaces”, Miguel Gomez, S.187 – 194
[3]
LaMothe Andre, "Beginning Direct3D Game Programming", Prima Publishing, Inc, 2001, Roseville, California 95661, ISBN 0-7615-3191-2
"Cubic Environment Mapping", Wolfgang F. Engel, S. 175 - 182
[4]
Foley, van Dam, Feiner, Hughes, “Computer Graphics: Principles and
Practice”, Addison-Wesley Publishing Company, 1990, ISBN 0-201-121107
[5]
Stam Jos, „Real-Time Fluid Dynamics for Games“, Alias wavefront, Toronto, GDC 2003
[6]
Griebel Michael, Dornseifer Thomas, Neunhoeffer Tilman, „Numerische
Simulation in der Strömungsmechanik – Eine praxisorientierte Einführung“,
vieweg Verlagsgesellschaft mbH, Braunschweig/Wiesbaden 1995, ISBN
3-528-06761-6
[7]
Krüger Jens, Westermann Rüdiger, “Linear Algebra Operators for GPU
Implementation of Numerical Algorithms”, 2003
[8]
Stoer Josef, “Numerische Mathematik”, Springer-Verlag, 1999, ISBN 3540-66154-9
[9]
Lomax, Pulliam, Zingg, “Fundamentals of Computational Fluid Dynamics
(Scientific Computation)”, Springer-Verlag, 2001, ISBN 3-540-41607-2
[10]
Tveito Aslak, Winther Ragnar, „Einführung in partielle Differentialgleichungen. Ein numerischer Zugang“, Springer-Verlag, 2002, ISBN 3-540-424040
[11]
Hungerbühler Norbert, “Einführung in partielle Differentialgleichungen“, vdf
Hochschulverlag AG, Zürich, 1996, ISBN 3-7281-2303-X
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 94 von 99
[12]
van Kann J. J. I. M., „Numerik partieller Differentialgleichungen für Ingenieure“, ISBN 3-519-02968-5
[13]
Fedkiw Ron, Osher Stanley, „Level Set Methods and Dynamic Implicit Surfaces”, Springer Heidelberg US, 2002, ISBN 0387954821
[14]
Schneider Jens, Westermann Rüdiger, “Towards Real-Time Simulation of
Water Surfaces”, 2001
[15]
Mircosoft, DirectX 9.0 SDK, 2002, http://www.microsoft.com/DirectX
[16]
Bui-Tuong Phong, “Illumination for Computer Generated Pictures”, CACM,
1975, 331 – 317
[17]
Blinn, J.F., “Models of Light Reflection for Computer Synthesized Pictures”,
SIGGRAPH 77, 192-198
[18]
nVidia, 2002, “Cube Maps”, http://developer.nvidia.com
[19]
Hammer, Hammer, “Physikalische Formeln und Tabellen”, Lindauer Verlag, München, 1994, ISBN 3-87488-064-8
[20]
Hirt, C., Nichols, B. & Romero, “SOLA – A Numerical Solution Algorithm for
Transient Fluid Flows”, Technical Report, Los Alamos Scientific Lab. Rep.
LA-5852
[21]
Bild eines Mercedes: http://www.oeamtc.at/netautor/data/auto/webuse/
mercedes_ekl2002seitl_4.jpg
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 95 von 99
Abbildungsverzeichnis
Abbildung 1: Schematischer Aufbau der Hardware .................................................... 5
Abbildung 2: Aufbau einer Grafikkarte........................................................................ 6
Abbildung 3: Membran und Koordinatenachsen....................................................... 10
Abbildung 4: Einfluss der Nachbarpunkte in der diskreten Wellengleichung ............ 12
Abbildung 5: Diskretes Gitter zur Modellierung der Membran .................................. 13
Abbildung 6: Dämpfungsfunktion in der Wasserdemo.............................................. 16
Abbildung 7: Regentropfeneinschläge und Wellenausbreitung ................................ 17
Abbildung 8: Große Einschläge und Wellenausbreitung .......................................... 18
Abbildung 9: Berechnung einer Dreiecksnormalen................................................... 20
Abbildung 10: Nachbarschaftsbeziehung ................................................................. 20
Abbildung 11: Phong-Illumination-Model .................................................................. 22
Abbildung 12: Materialspezifische Konstante n ........................................................ 24
Abbildung 14: Reflexionsvektor ................................................................................ 25
Abbildung 13: Regentropfeneinschläge von oben mit Phong-Beleuchtung .............. 26
Abbildung 15: Sechs Seiten einer Cube-Map ........................................................... 27
Abbildung 16: Reflexion der Umgebung im Wasser ................................................. 27
Abbildung 17: Brechungsvektor................................................................................ 28
Abbildung 18: Lichtbrechung .................................................................................... 30
Abbildung 19: Texturen und Funktionsweise des Wellen-Pixel-Shaders.................. 31
Abbildung 20: Funktionsweise des Licht-Pixel-Shaders ........................................... 33
Abbildung 21: Geschwindigkeitsmessungen der Demo Water2D............................. 34
Abbildung 22: Displacement Mapping ...................................................................... 35
Abbildung 23: Geschwindigkeitsmessungen der Demo Water2D............................. 36
Abbildung 24: Water3D mit 64² Gitterzellen, Phong-Beleuchtung und Lichtreflexion 36
Abbildung 25: Laminare Strömungen ....................................................................... 37
Abbildung 26: Diskretisiertes Gebiet mit Randzellen ................................................ 42
Abbildung 27: Staggered Grid .................................................................................. 43
Abbildung 28: Weiße Fluidzellen, graue Hinderniszellen, ungültige Zellen in Rot .... 44
Abbildung 29: Gauss-Seidel-Verfahren .................................................................... 52
Abbildung 30: Vertex-Buffer Full, Inner (grau), Top0, Bottom0, Left0, Right0........... 58
Abbildung 31: Randbedingungen im Staggered Grid ............................................... 59
Abbildung 32: Dynamischer Zusammenbau des BoundaryUV-Shaders .................. 61
Abbildung 33: Farbkodierung der Richtungsvektoren............................................... 69
Abbildung 34: Einströmung von links nach rechts mit Wirbelbildung........................ 70
Abbildung 35: Partikelverfolgung .............................................................................. 72
Abbildung 36: Partikel mit Feuerpalette .................................................................... 72
Abbildung 37: Intensitätspalette und Positionspalette .............................................. 73
Abbildung 38: Partikelpinsel ..................................................................................... 73
Abbildung 39: Beispiel einer Druckverteilung ........................................................... 74
Abbildung 40: Rotation der Wirbelstrasse................................................................. 74
Abbildung 41: Hindernisse mit ungültigen Zellen...................................................... 75
Abbildung 42: Overlay Texturen ............................................................................... 76
Abbildung 43: Geschwindigkeit bei Visualisierung des Geschwindigkeitsfelds ........ 77
Abbildung 44: Geschwindigkeit bei Visualisierung der Wirbelstärke......................... 78
Abbildung 45: Geschwindigkeit von Partikeln, Druck oder Hindernissen.................. 78
Abbildung 46: Nischenströmung............................................................................... 79
Abbildung 47: Vektorfeld einer Nischenströmung mit hoher Reynoldszahl .............. 80
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 96 von 99
Abbildung 48: Partikelverfolgung in der Nischenströmung ....................................... 80
Abbildung 49: Kármánsche Wirbelstraße ................................................................. 81
Abbildung 50: Strömung über einen schrägen Balken mit hoher Reynoldszahl ....... 81
Abbildung 51: Partikelverfolgung über den schrägen Balken ................................... 82
Abbildung 52: Simulation eines Flusses (Partikelverfolgung) ................................... 82
Abbildung 53: Simulation eines Flusses (Geschwindigkeitsfeld) .............................. 82
Abbildung 54: Strömung über eine Stufe.................................................................. 83
Abbildung 55: Stufenströmung mit Re = 1000 (Geschwindigkeitsfeld) ..................... 84
Abbildung 56: Stufenströmung mit Re = 1000 (Partikelverfolgung) .......................... 84
Abbildung 57: Auto im Windkanal (Geschwindigkeitsfeld) ........................................ 85
Abbildung 58: Auto im Windkanal (Geschwindigkeitsfeld) ........................................ 85
Abbildung 59: tum3D-Logo (Geschwindigkeitsfeld) .................................................. 86
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 97 von 99
Stichwortverzeichnis
Ableitungen, partiell ..........................11
Advektion..........................................40
Ähnlichkeit ........................................38
Ambient-Anteil ..................................23
Anfangsbedingungen........................39
Anfangswert-Randwert-Problem.......39
ATI Radeon 9700 .............................33
Auftriebskraft ....................................89
Auslenkung.........................................9
Auslöschungen .................................88
Bandmatrix .......................................51
Betrachtungsvektor...........................24
Bilder pro Sekunde .....................34, 77
Bildschirm
Auflösung ......................................76
Speicher........................................77
Boussinesq-Appromixation ...............90
Brechungsindex................................28
clFramework ...............................53, 60
Collcated Grid...................................43
Courant-Friedrichs-Levi-Bedingungen
......................................................45
Cube-Maps .................................26, 33
Dämpfung .........................................15
Dämpfungstextur ..............................31
Differentialgleichung .........................38
Differenzenverfahren, finite.........11, 46
Diffusion................................40, 50, 71
Rate ..............................................71
Direct3D-Device ...............................56
DirectX..................................55, 62, 64
Displacement Mapping .....................35
Divergenz .........................................53
Divergenzfreiheit...................38, 39, 49
Doner-Cell-Diskretisierung................48
Dreiecksdurchsatzraten ......................5
Dreiecksnormale...............................19
Druck ..............................39, 40, 69, 74
Randbedingung.............................60
Druckrandwerte ................................89
Durchflussgeschwindigkeit ...............10
Einflusskraft ......................................50
Einschlag ..........................................16
Radius .......................................... 17
Tiefe ............................................. 17
Epsilon-Schranke............................. 54
Explizites Verfahren....................14, 46
Exponentialfunktion ......................... 15
Fehlerterm ....................................... 11
Fixed-Function-Pipeline ................... 65
Fluid................................................. 37
Element ........................................ 40
inkompressibel ............................. 37
instationär..................................... 37
laminar ......................................... 37
Zelle ............................44, 45, 56, 89
Framebuffer ..................................... 58
Freie Randwertprobleme ................. 89
Gausselimination ............................. 51
Gauss-Seidel-Verfahren .......52, 53, 88
Geometrieeinheit ............................. 35
Geschwindigkeit
Feld ...................................69, 74, 77
Messung..................................55, 76
Geschwindigkeitsfeld ..................87, 89
Gitter
Auflösung ..................................... 76
regulär .....................................12, 13
versetzt ........................................ 43
Zelle ............................................. 76
Gleichungssystem ........................... 51
GPU................................................... 5
Grafik-API ........................................ 55
Graphical Processing Unit ................. 5
Halbvektor ....................................... 25
Hauptspeicher.................................... 5
High-Level-Shader-Language..............
..........................................55, 64, 67
Hindernis ......44, 56, 69, 75, 79, 81, 83
Bitfeld ........................................... 56
Editor.......................................75, 88
Information ................................... 56
Randbedingung.......................44, 56
Shape-Wert .............................56, 60
Shift-Wert ................................56, 60
Textur ......................................68, 75
Zelle ....44, 45, 56, 60, 68, 75, 88, 89
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Seite 98 von 99
Implizites Verfahren..........................14
Impulsgleichung....................................
.................. 37, 38, 42, 46, 50, 68, 90
Instabilität, numerische.....................14
Interpolation, bilinear ..................65, 77
Isolinien ............................................87
Iterationsschritt ...................................9
Phong-Illumination-Model ....................
....................................19, 22, 25, 35
Pixel-Shader .......................5, 6, 59, 88
Pixel-Shader 2.0 Standard....33, 59, 67
Pixel-Shader 3.0 Standard....59, 89, 92
Pixel-Shader-Einheiten ...................... 7
Poisson-Gleichung..................9, 49, 51
Konjugierte Gradienten-Verfahren........
................................................53, 54
Konstantenregister ...........................68
Kontinuitätsgleichung ...........................
..............................37, 38, 42, 49, 51
Konvektion..................................40, 50
Randbedingung ............................... 41
Ausströmbedingung ..................... 41
Einströmbedingung ...................... 41
Haftbedingung.........................41, 79
Rutschbedingung ......................... 41
Rechenfehler ................................... 88
Rechengeschwindigkeit ................... 76
Reflexionsvektor .............................. 25
Rendering Pipeline .......................... 62
Residuum ........................................ 54
Reynoldsgleichungssystem ............. 37
Reynoldszahl ............38, 45, 79, 81, 83
Rotation ......................................69, 74
Rückwärtsdifferenz .......................... 11
Rückwärtsverfolgung ....................... 71
Licht
Anteil, diffuse ................................23
Berechnung...................................34
Brechung.....................19, 28, 33, 35
Farbe.......................................19, 24
Intensität .................................19, 24
Quelle......................................19, 22
Reflexionen .......................19, 33, 35
Refraktion......................................33
Strahl.......................................19, 28
Vektor............................................23
Massenerhaltung ........................38, 39
Membran ............................................9
Microsoft ...........................................55
Navier-Stokes-Gleichungen..................
................... 8, 37, 38, 42, 44, 45, 54,
....................................76, 87, 90, 91
dimensionsbehaftet.......................38
dimensionslos ...............................38
Diskretisierung ..............................42
Nischenströmung........................60, 79
Numerische Fehler ...........................88
Oberflächenkräfte .............................40
Oberflächennormale ...................19, 23
Oberflächenspannung ........................9
Oszillationen .....................................45
Parallelrechner ...................................7
Partikel .....................60, 69, 73, 77, 89
Diffusion ........................................60
Pinsel ......................................60, 73
Verfolgung.............56, 60, 71, 87, 89
Schattentextur.............................52, 56
Shader ......................................... 5, 32
Shader-Länge .................................. 59
Shader-Quellcode............................ 61
Simulation, numerische ..................... 8
Simulationstyp ................................. 61
Driven Cavity...........................60, 79
Inject ............................................ 61
Ocean ...............................61, 81, 83
Waterfall ....................................... 60
Stabilitätsbedingung ........................ 45
Stabilitätsfaktor ................................ 45
Staggered Grid ....................................
............43, 45, 47, 50, 55, 56, 57, 58
Strahlenverlauf................................. 22
Stromfunktion................................... 87
Stromlinien....................................... 87
Strömung ..................................... 8, 37
Stufenströmung ..........................61, 83
Taylor-Formel .................................. 11
Technique ........................................ 67
Temperatur ...................................... 89
Textur .............................31, 55, 57, 92
Echtzeitfähige Simulation von Wasser auf Grafikhardware
Überschwinger..................................14
Ufer...................................................15
Vektornormale ..................................19
Vertex-Buffer ..............................55, 57
Vertexnormale ..................................19
Vertex-Shader ........................6, 58, 59
Vertex-Shader 3.0 Standard .............92
Video-Speicher ...................................5
Viskosität ..........................................39
Visualisierung ...................................77
Visualisierungstechnik ..........................
..............................69, 74, 76, 77, 87
Volumenrenderer..............................90
Vorwärtsdifferenz..................11, 46, 47
Vorwärtsverfolgung...........................71
Wasser ...............................................9
Durchlässigkeit..............................10
Seite 99 von 99
Membran ...................................... 33
Oberfläche.............................8, 9, 13
Water2D .......................................... 33
Water3D .....................................33, 35
Wellen................................................ 9
Bewegungen .................................. 9
Geschwindigkeit ........................... 10
Gleichung ....................................... 8
Kämme......................................... 19
Shader ......................................... 31
Textur ......................................31, 33
Wirbel .............................................. 74
Stärke................................74, 77, 87
Straße .....................................38, 61
Straße, Kármánsche ...............81, 85
Zähigkeit .......................................... 39
Zeit..............................................39, 45
Zentraldifferenz................................ 11