Heiko Senger

Transcription

Heiko Senger
Hauptseminar
Prof. Dr. Nischwitz
Volumetrische Effekte mit Voxelsystemen
Heiko Senger
Matr.-Nr.: 03447602
Studiengruppe: IGM3
[email protected]
30. Juni 2009
1
Erklärung
gemäß § 35 Abs. 7 RaPO
Heiko Senger
geboren am 11.04.1981 in Weilheim i. Obb.
Matrikelnummer 03447602
Studiengruppe IGM3
Sommersemster 2009
Hiermit erkläre ich, dass ich die Studienarbeit selbständig verfasst, noch nicht anderweitig
für Prüfungszwecke vorgelegt, keine anderen als die angegebenen Quellen oder Hilfsmittel
benützt, sowie wörtliche und sinngemäße Zitate als solche gekennzeichnet habe.
München, am 30. Juni 2009
Heiko Senger
2
Inhaltsverzeichnis
1 Einführung
4
2 Volumentrische Effekte
4
3 Volume-Rendering
3.1 Volumendaten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Transferfunktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 Renderverfahren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
6
7
7
4 Rauch und Feuer mit Volumenrendering
4.1 Simulation . . . . . . . . . . . . . . . .
4.1.1 Modellierung . . . . . . . . . .
4.1.2 Lösung . . . . . . . . . . . . . .
4.1.3 Berücksichtigung von Objekten
4.1.4 Effektspezifische Einflussgröße .
4.2 Rendern . . . . . . . . . . . . . . . . .
4.2.1 Vorverarbeitung . . . . . . . .
4.2.2 Raycasting . . . . . . . . . . .
4.3 Rauch und Feuer . . . . . . . . . . . .
4.3.1 Weitere Problemstellungen . .
4.3.2 Artefakte . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
11
11
11
13
15
16
17
17
18
19
20
21
5 Vergleich zu Partikelsystemen
23
6 Zusammenfassung
27
3
1 Einführung
In dieser Arbeit wird ein Verfahren zum Rendern von volumetrischen Effekte durch
Volume-Rendering auf der Grafikkarte vorgestellt. In Abschnitt 2 werden hierfür die
Grundlagen vermittelt. Dazu wird zunächst kurz erklärt, was man unter volumetrischen
Effekten versteht, was Volume-Rendering ist und welche Ansätze es hierfür gibt. Danach
wird in Abschnitt 3 auf ein konkretes Verfahren eingegangen, das Feuer und Rauch durch
Fluiddynamik in einem Volumen simuliert. Zur Visualisierung des Effektes wird Raycasting verwendet. Abschließen werden volumenbasierte Ansatz und der heutige Standard,
die Partikelsystem, miteinander verglichen.
Was in dieser Arbeit nicht besprochen wird, sind Schatten, Self-Shadowing oder Beleuchtung. Hierfür sei auf [AS09] und [FSJ01] verwiesen.
2 Volumentrische Effekte
Unter den Begriff der volumentrischen Effekte fallen in der Computergrafik eine breite
Palette von Effekten. Hierzu zählen Effekte wie Feuer, Staub, Nebel, Wolken, Rauch,
Explosionen oder auch Flüssigkeiten. Im Unterschied zu den „normalen“ Objekten in der
Computergrafik, haben diese Effekte keine Oberfläche oder feste Form. Sie bestehen nicht
nur aus einer leeren Hülle von Polygonen, sondern existieren, wie der Name schon sagt,
über ein Volumen. Zwar ist es möglich einige dieser Effekte über animierte Texturen
darzustellen wie zum Beispiel Feuer oder Wolken, jedoch bringt die Natur dieser Effekte
es mit sich, dass die Kamera auch im Inneren dieser Effekte sein kann, wodurch der
„Schwindel“ sofort auffliegt.
Der klassische Ansatz zu Realisierung von volumetrischen Effekten sind Partikelsysteme.
Hierbei werden viele einzelne Objekte – Partikel – erzeugt die als Ganzes einen Effekt
erzeugen. Ein Partikel wird dabei durch ein Objekt (z.B. Kugel), eine Textur (z.B. Feuertextur) oder einfach nur ein Punkt mit einem Farbwert dargestellt (Abbildung 1).
Abbildung 1: Partikelsystem: Einmal als Rauch und einmal als Würfelpartikel gerendert
[Wik09b]
4
Ein anderer Ansatz zum Erzeugen von volumetrischen Effekten, der auch der Kern dieser Arbeit ist, basiert auf dem Volume-Rendering. Volume-Rendering ist eine Darstellungsverfahren, dass sehr stark im medizinischen Umfeld im Einsatz ist [Wat00]. Hierbei
werden im Gegensatz zum oberflächenbasierten Rendern nicht nur die Oberflächen eines
Objektes berücksichtigt, sondern auch dessen Inneres. Dies ist besonders bei medizinischen Bildern wichtig, da oft der Querschnitt vom Objektinneren von Interesse ist (z.B.
für Knochen und Organe).
Im Folgenden werden einige Effekte beschrieben, die in der Computergrafik häufig vorkommen sind. Dabei ist zu beachten, dass die Beschreibung nicht den Anspruch einer
korrekten physikalischen Definition hat. Vielmehr handelt es sich hierbei um eine allgemeine Beschreibung um ein grobes Verständnis dafür zu bekommen.
Feuer Bei Feuer handelt es sich um eine chemische Verbrennung, die sich optisch durch
eine Flammenbildung zeigt. Bei diesem Vorgang wird Licht und Wärme abgegeben.
Notwendig für die Entstehung eines Feuers sind Sauerstoff, Brennmaterial und die
davon abhängige Zündtemperatur. Diese sind auch für das grundlegende Erscheinungsbild verantwortlich, das noch durch Luftströmungen (z. B. Wind) beeinflusst
werden kann.
Staub / Rauch / Wolken / Nebel Bei diesen Effekten handelt es sich um ähnliche Phänomene die unterschiedliche Ursachen haben. So ist zum Beispiel Rauch das Ergebnis eines Verbrennungsprozesses und Wolken das Ergebnis einer Verdunstung von
Wasser. Allen gemein ist, dass ihr Aussehen (Farbe, Form und Bewegung) von der
der Dichte und Größe der Schwebeteilchen, Gasen, Temperatur und externen Faktoren wie Lichtquellen oder Krafteinwirkung (Gravitation, Wind) abhängig sind.
Je nach Effekt werden bestimmte Eigenschaften stärker gewichtet um das charakteristische Aussehen zu erhalten.
Explosionen Eine Explosion ist ein plötzlicher Anstieg von Temperatur und/oder Druck,
welcher eine plötzliche Volumenausdehnung von Gasen und der Freisetzung von
Energie auf engen Raum zur Folge hat. Die häufigsten Explosionen in der Computergrafik sind wohl die chemischen Explosionen, bei denen es zu Flammen-, Rauchund Staubbildung kommt.
Flüssigkeiten Hierbei handelt es sich um einen Stoff in einem flüssigen Aggregatzustand.
Flüssigkeiten leisten Formveränderungen so gut wie keinen Widerstand und sind
nahezu inkompressibel. Das Erscheinungsbild sind auch von Art, Größe und Dichte
der Teilchen in der Flüssigkeit und von externen Faktoren wie Lichtquellen und
Krafteinwirkung abhängig. Im Unterschied zu anderen Effekten verfügen Flüssigkeiten über eine Oberfläche auf der sich andere Effekte wie Reflexion oder der
Fresnel-Effekt zeigen können.
5
3 Volume-Rendering
Wie im vorherigen Abschnitt bereits erwähnt, konzentriert sich diese Arbeit auf die Darstellung von volumetrischen Effekten durch Volume-Rendering. Unter Volume-Rendering
versteht man das Visualisieren von Volumendaten. Dieser Abschnitt geht nun auf Techniken ein, mit den dies realisiert werden kann.
3.1 Volumendaten
Im Gegensatz zum oberflächenbasierten Rendern liegen die Daten nicht als Dreiecke /
Polygone vor, sondern als Volumen. Diese werden durch Voxel (Volumenelement) dargestellt. Für ein Voxel gibt es zwei verschiedene Formen bzw. Betrachtungsmöglichkeiten:
Einerseits kann ein Voxel als ein Abtastpunkt betrachtet werden, der sich in der Mitte eines Volumens befindet. Der Wert des Voxels ist hierbei im ganzen Volumen gleich.
Eine andere Betrachtungsweise ist die der Voxelzelle. Sie wird durch acht Abtastpunkte
dargestellt, die einen Würfel bilden. Der Wert an einer Position innerhalb eines Voxels
ergibt sich dann durch Interpolation der Werte an den Eckpunkten. Ein Voxel kann
ein oder mehrere Werte haben. Diese sind in der Regel keine Farbwerte, sondern physikalische Größen wie Dichte oder Temperatur. Diese werden über eine Transferfunktion
auf einen Farb- und Transparenzwert abgebildet. Die Voxel werden in einem regulären
kartesischen Gitter angeordnet, die dann den Volumendatensatz bilden. Abbildung 2
verdeutlicht nochmal die beiden Formen.
Abbildung 2: Darstellung eines Voxel als Punkt (links) und als Zelle (rechts)
Grundsätzlich kann ein Voxel auch ein Tetraeder und der Datensatz kann auch irregulär
sein.
6
3.2 Transferfunktion
Voxel beinhalten in der Regel keine Farbwerte, sondern physikalische Größen wie beispielsweise Dichte, Temperatur, usw.. Wird nun ein Farbwert benötigt, so muss dieser
aus diesen Größen abgeleitet werden. Im einfachsten Fall geschieht dies mit einer LookupTable. Hierbei wird der Voxelwert auf einen Farbwert abgebildet. Typischerweise wird
dies mit einer eindimensionalen Textur realisiert. Abbildung 3 zeigt dies anhand einer
Farbtemperaturskala. Dabei erhält Temperaturwert von 4000 Kelvin die Farbe weiß.
Hierbei ist zu beachten, dass dies nicht der menschlichen Farbwahrnehmung entspricht,
da dieser die Farbe weiß ab etwa 1500 Kelvin (Weißglut) wahrnimmt.
Abbildung 3: Farbtemperatur nach dem planckschen Strahlungsgesetz [Wik09c]
3.3 Renderverfahren
Zu Visualisierung von Volumendaten, gibt es eine Reihe von Verfahren, die sich in zwei
Klassen einteilen lassen:
• indirektes Volume-Rendering
• direktes Volume-Rendering
Beim indirekten Volume-Rendering wird versucht aus den Volumendaten die Oberfläche
zu extrahieren. Das Ergebnis dieses Prozesses ist eine Menge von Polygonen / Dreiecken,
die mit dem klassischen oberflächenbasierten Rendern dargestellt werden können.
Einer der bekanntesten Algorithmen hierfür ist der Marching-Cube-Algorithmus. Dies
ist ein Verfahren zur Oberflächenextraktion. Hierbei wird jeder Eckpunkt eines Voxels
mit einer 1 oder 0 versehen, je nachdem ob sich dieser Punkt im Inneren (hinter einer
Oberfläche) oder außerhalb (vor einer Oberfläche) des Objektes befindet. Durch diese Voxelkodierung lässt sich eine acht stellige Binärzahl bilden. Es gibt somit theoretisch 256
Möglichkeiten, wie eine Oberfläche eine Zelle schneiden kann. Aufgrund von einigen geometrischen Eigenschaften, lassen sich diese auf 15 Stück reduzieren [Wat00] (Abbildung
4)
Die letztendliche Position der Dreiecksflächen hängt vom Voxelwert an den Ecken ab.
Daraus wird ein Polygon-Mesh erstellt, das an die Grafikkarte übergeben und regulär
gerendert wird. Eine Implementierung wird in [WW92] beschrieben. Eine fertige Implementierung des Marching-Cube-Algorithmus gibt es von Nvidia im CUDA SDK [Nvi].
7
Abbildung 4: 15 Möglichkeiten, wie ein Voxel durch eine Oberfläche geschnitten werden
kann [c09]
Im Gegensatz zum indirekten Rendern, werden beim direkten Rendern keine Polygone
generiert, sondern der Farbwert wird für jedes Pixel direkt berechnet. Hierfür haben sich
eine Reihe von Verfahren bewährt:
Volume Raycasting Beim Raycasting wird für jedes Pixel ein Strahl auf den Volumendatensatz geschossen, der dabei ein oder mehrere Voxel durchquert. Die Volumendaten
werden dabei entlang des Strahls, in regelmäßigen Abständen, abgetastet (Abbildung
5). An den Abtastpunkten wird der Voxelwert ermittelt. Der Wert hängt dabei von der
Postion des Abtastpunktes im Voxel ab oder von der Strecke des Stahls innerhalb des
Voxel. Die endgültige Farbe wird dann mit der Transferfunktion erzeugt, die entlang
des Strahls akkumuliert wird. Dieser Vorgang kann dabei von vorne nach hinten oder
umgedreht geschehen.
Splatting Splatting ist ein von Westover [Wes90] vorgestelltes Voxelprojektionsverfahren, bei dem eine Ebene, entlang der Sichtrichtung, durch den Volumendatensatz wandert
und die Voxel auf die Ebene projiziert werden. Da ein Voxel in der Regel größer ist als
ein Pixel muss bestimmt werden, welche Werte die Pixel auf der Ebene erhalten. Dies geschieht über ein dreidimensionale Filterung. Als Filter kann zum Beispiel ein Gausskern
verwendet werden, der einen kreisrunden Abdruck auf der Bildebene erzeugt (Abbildung
6). Die projizierten Werte werden im Framebuffer akkumuliert. Der Vorgang kann von
Vorne nach Hinten oder umgedreht durchgeführt werden. Bildlich lässt sich das Ganze
so vorstellen, als ob man mit einem Auto durch einen Insektenschwarm fährt und diese
gegen Windschutzscheibe klatschen (engl. to splat).
8
Abbildung 5: Raycasting
Texturbasierten Render Beim texturbasierten Render wird der Volumendatensatz in
einer 3D Textur geladen. Dieser Datensatz wird dann mit n Ebenen geschnitten, die
parallel zur Bildebene sind. Jede Ebene erzeugt mit den Schnittkanten der BoundingBox des Datensatzes ein Polygon, die sogenannte Proxy-Geometrie. Diese wird dazu
verwendet um den Volumendatensatz abzutasten (Abbildung 7).
Nun wird die Proxy-Geometrie sequentiell von vorne nach hinten oder umgedreht gezeichnet. Dabei wird für jedes Fragment die 3D-Textur bzw. der Volumendatensatz nun
mit einer trilineare Interpolation abgetastet und mit der bisherigen Pixelfarbe vermischt.
Ikits zeigt in [IKLH04] wie sich diese Verfahren auf einer Grafikkarte realisieren lässt.
9
Abbildung 6: Projektion eines Voxel auf die Ebene mittels Gausskern
Abbildung 7: Proxy-Geometriy [IKLH04]
10
4 Rauch und Feuer mit Volumenrendering
Feuer und Rauch sind klassische Effekte in der Comptergrafik. In diesem Abschnitt wird
ein Verfahren vorgestellt, mit dem diese simuliert und mit einem volumenbasierten Renderverfahren visualisiert werden. Dieser Abschnitt basiert in erster Linie auf dem Artikel
Real-Time Simulation and Rendering of 3D Fluids von Crane et al. [CLT08]. Darin
wird ein Verfahren vorgestellt, das unter Verwendung von Computational Fluid Dynamics (CFD) Rauch, Feuer und Flüssigkeiten simuliert, die außerdem auf bewegliche und
statische Hindernisse reagieren. Diese Arbeit beschränkt sich allerdings auf Feuer und
Rauch. Die Wahl fiel auf dieses Verfahren, weil sowohl Simulation als auch das Rendern
auf der Grafikkarte berechnet wird und weil es seine Praxistauglichkeit bereits in dem
Computerspiel Hellgate London unter Beweis gestellt hat [CLT08].
Dieser Abschnitt ist in zwei Teile aufgeteilt. Im ersten Teil wird kurz auf das Simulationsverfahren eingegangen, durch das der Volumendatensatz für einen Zeitpunkt generiert
wird. Danach wird im zweiten Teil auf das Renderverfahren eingegangen, dass dazu verwendet wird um den Volumendaten zu visualisieren.
4.1 Simulation
Feuer und Rauch sind keine statischen Effekte, sondern sind ständig in Bewegung. Als
Mensch ist man mit diesen Effekten vertraut und hat somit eine gewisse Erwartung
an dessen Bewegungsverhalten. Diese Effekte werden durch Strömungen verursacht, die
Teilchen durch ein Medium bewegen. Diese Strömung selbst wird dabei von verschiedenen
Größen beeinflusst, wie externe Kräfte, Dichte, Hindernisse und/oder Druck.
Mit dieser Problematik setzt sich die Fluiddynamik auseinander. Diese befasst sich mit
der Bewegung von Fluiden. Ein Fluid ist ein strömendes Medium, also Flüssigkeiten
und Gase. Es gibt eine Reihe von Modellen mit den sich diese beschreiben lassen. Zur
algorithmischen Lösung dieser Problemstellung hat sich die numerische Strömungsmechanik (engl. computational fluid dynamics) etabliert. Ein Einblick in diese Thematik
gibt Laurien und Oertel in [LOj09].
4.1.1 Modellierung
Zur Modellierung der Fluide haben sich eine Reihe von Gleichungen etabliert. Einen
Überblick gibt [LOj09]. Eine der bekanntesten ist wohl die Navier-Stock-Gleichung. Diese gibt es für kompressible und inkompressible Fluide. Ein Fluid ist kompressibel wenn
durch Krafteinwirkung die Dichte und somit das Volumen verringert werden kann. Beispiel hierfür sind Gas, wohingegen Flüssigkeiten so gut wie inkompressibel sind [LOj09].
Harris verwendet in [Har04] die Navier-Stockes-Gleichung für inkompressible Fluide. Die
11
vereinfachte Annahme der Inkompressibilität ist auch bei kompressiblen Medien oft gerechtfertigt da, diese in Bereichen, wo sich die Dichte nicht ständig ändert keinen signifikanten Einfluss auf die Simulation hat [LOj09][Har04]. Gleichung 1 und 2 beschreiben
Navier-Stokes-Gleichung für inkompressible Fluide.
∂u
1
= −(u · ∇)u − ∇p + ν∇2 u + F
∂t
ρ
(1)
∇·u=0
(2)
Harris [Har04] beschreibt die vier Terme auf der rechten Seit von Gleichung 1 (von links
nach rechts) als Advektion, den Druck, die Diffusion und eine externe Kraft.
Advektion Advektion beschreibt den Transport von Objekten oder Eigenschaften in
Fluiden abhängig von der Geschwindigkeit. Dies ist durch den Advektionsoperator −(u · ∇) beschrieben. Der ganze Term beschreibt dabei die Selbstadvektion des
Geschwindigkeitsfeldes u.
Druck Der zweite Term beschreibt die Beschleunigung die sich durch den Druck ergibt.
Dieser entsteht dadurch, dass Moleküle innerhalb eines Fluides eine Krafteinwirkung nicht sofort an das ganze Fluid weitergeben, sondern dass diese sich an einem
Ort verdichten. ρ ist hierbei die Dichte, die im inkompressiblen Fall konstant ist. p
steht für den Druck, also die Kraft pro Flächeninhalt.
Diffusion Dieser Term beschreibt die Zähflüssigkeit von Fluiden. Diese wird durch die
Viskosität ν angegeben, die von Fluid zu Fluid unterschiedlich. So ist zum Beispiel
Sirup zähflüssiger als Wasser.
Externe Kraft Dieser Term beschreibt die Beschleunigung die durch externe Krafteinwirkung stattfindet. Diese können lokal sein, d. h. sie wirken nur auf einen Bereich
des Fluids (z.B. Windhauch) oder global und wirken auf das ganze Fluid (z. B.
Erdanziehung).
Gleichung 2 ist die Kontinuitätsgleichung. Diese beschreibt Inkompressibilität des Fluids,
durch die Divergenzfreiheit von u. In [CLT08] wird auf den Diffusionsterm verzichtet,
wodurch die Gleichung zur Euler-Gleichung vereinfacht wird.
∂u
1
= −(u · ∇)u − ∇p + F
∂t
ρ
(3)
Ein Grund hierfür wird nicht explizit genannt. Jedoch liegt der Verdacht nahe, dass er die
Gleichung vereinfachen wollte, da die Viskosität für Feuer und Rauch vernachlässigbar
ist und sie somit den Wert ν = 0 hat, wodurch der Diffusionsterm weg fällt. Im Folgenden
wird nur noch die Euler-Gleichung verwendet.
12
4.1.2 Lösung
Gleichung 3 ist ein nichtlineares partielles Differenzialgleichungssystem 1. Ordnung mit
vier Gleichungen und vier Unbekannten ux , uy , uz und p.
∂ux
1
= −(u · ∇)ux − ∇p + F
∂t
ρ
∂uy
1
= −(u · ∇)uy − ∇p + F
∂t
ρ
1
∂uz
= −(u · ∇)uz − ∇p + F
∂t
ρ
Das hier gezeigte Verfahren basiert auf dem von Stam [Sta99] vorgestellten Verfahren,
dass von Harris [Har04] auf der GPU realisiert wurde und von Crane et al. [CLT08] auf
den dreidimensionalen Fall erweitert wurde. Im Folgenden wird nur die grundsätzliche
Vorgehensweise und die verwendeten Verfahren kurz vorgestellt um ein Gefühl dafür zu
bekommen. Für eine genaue mathematische Beschreibung sei auf [Sta99] verweisen. Eine
Shader-Implementierung wird in [Har04] und [CLT08] gezeigt.
Die Lösung der Gleichung 3 wird in drei Schritten durchgeführt. Der erste Schritt besteht
darin, die Advektion zu lösen. Hieraus resultiert ein Geschwindigkeitsfeld auf das nun eine
externe Kraft addiert wird. Daraus ergibt sich das divergente Geschwindigkeitsfeld w,
woraus sich nun p bestimmen lässt [Har04]. Aus w und p wird nun u bestimmt werden.
Advektion Zur Lösung der Advektion kann das Semi-Lagrange-Verfahren verwendet.
Dies ist bei großen Zeitschritten stabil [Sta99] und lässt sich auf Fragment-Shadern Implementieren [Har04]. Bei diesem Verfahren wird die Geschwindigkeit eines Fluidelements
an der neuen Position zum Zeitpunkt t + δt, aus den Geschwindigkeiten in der Umgebung des Fluidelements der alten Position zum Zeitpunkt t − δt berechnet. Abbildung 8
verdeutlicht diesen Sachverhalt noch einmal.
Crane et al. [CLT08] schlagen eine Alternative zum Semi-Lagrange-Verfahren vor: das
MacCormack-Verfahren. Hierbei wird, vereinfacht gesagt, das Semi-Lagrange-Verfahren
zweimal pro Advektionsschritt angewendet. Einmal für eine Vorhersage der Advektion
und einmal für eine Korrekturrechnung dieser Vorhersage. Aus diesen beiden Ergebnissen wird dann die endgültige Advektion für den Schritt bestimmt. Das MacCormackVerfahren führt zu besseren Ergebnissen bei gleicher Gittergröße, da es eine höhere
Genauigkeit hat (Abbildung 9). Dies ist zwar rechenintensiver als das Semi-LagrangeVerfahren jedoch ist Rechenzeit auf der GPU günstig im Vergleich zur Speicherbandbreite.
13
Abbildung 8: Semi-Lagrange-Verfahren [Har04]
Abbildung 9: Links MacCormack-Verfahren (128x64x64),
Rechts: Semi-Lagrangian-Verfahren (256x128x128) [CLT08]
Externe Kraft Die externe Krafteinwirkung wird einfach durch eine Addition auf das
bisherige Geschwindigkeitsfeld der Advektion aufaddiert. Daraus ergibt sich nun das divergente Geschwindigkeitsfeld w.
Druck Durch anwenden des Helmholtz-Hodge-Zerlegung und der Berücksichtigung der
Kontinuitätsgleichung (Gleichung 2), ergibt sich die Poisson-Gleichung
∇2 p = ∇w .
(4)
Eine Herleitung hierfür ist [Har04] zu entnehmen. Mit dem Jacobi-Vefahren lässt sich
dieses System lösen, wodurch man den p erhält.
Gemäß dem Helmholtz-Hodge-Zerlegung [Har04]
14
u = w − ∇p ,
(5)
lässt sich nun u als Differenz von w und ∇p darstellen, womit alle Unbekannten bestimmt
sind.
4.1.3 Berücksichtigung von Objekten
Die bisherige Betrachtung geht davon aus, dass sich das Fluid alleine in einem Volumen
befindet, in dem es sich bewegen kann. Oft ist es aber der Fall, dass ein festes Objekt
von dem Fluid umgeben ist, dass dessen Bewegung beeinflusst. Des weiteren könnte sich
das Objekt auch noch bewegen, wodurch die Bewegung des Fluids auf unvorhergesehen
Weise beeinflusst wird. Abbildung 10 zeigt dies am Beispiels einer Figur, die den Rauch
mit seinen Flügel weg wedelt.
Abbildung 10: Figur, die mit ihrem Flügelschlag den Rauch wegwedelt [CLT08].
Der Effekt der hierbei entstehen soll, ist dass das Fluid an der Objektoberfläche entlang
fließt. Dabei soll das Fluid keinesfalls in das Objekt hinein fließen. Dies muss bei der
Lösung des Druckterms berücksichtigt werden, da Voxel, die innerhalb eines Objektes
sind, keinen Einfluss auf den Druck haben sollen. Wie dies mathematisch berücksichtigt
wird, wird in [CLT08] beschrieben.
Für diese Berücksichtigung muss bekannt sein, welche Voxel innerhalb des Objektes sind,
und welche Geschwindigkeit das Objekts hat. Um diese Daten zu bestimmen, stellen
Crane et al. ein Verfahren in [CLT08] vor, bei dem das Objekt schnell voxelisiert werden
kann.
Hierbei werden zunächst mehrere Querschnitte des Objektes erzeugt. Das Verfahren das
Crane et al. verwenden ist an den Stencil-Shadow-Volume-Algorithmus angelehnt. Das
Ergebnis dieses Prozesses sind mehrere Schwarz-Weiß-Texturen, die den Querschnitt des
Objektes an verschiedenen Stellen zeigen (inside-outside texture). Abbildung 11 (oben
rechts) verdeutlicht dies. Weiße Bereiche sind dabei außerhalb und schwarze innerhalb
des Objekts.
15
Danach muss die Geschwindigkeit für das Objekt bestimmt werden. Hierbei wird zunächst die Geschwindigkeit an den Vertices des Objekts bestimmt. Danach kann durch
Interpolierung die Geschwindigkeit von den Vertices auf die Voxel übertragen werden.
Das Ergebnis ist wird in Abbildung 11 (unten rechts) dargestellt. Es ist ein Vektorfeld in
Form einer Textur, dass die interpolierten Geschwindigkeiten am Objektrand speichert
(velocity texture). Hierfür kann auch ein vereinfachtes Modell mit gröberen Geometrie
verwendet werden, um den Prozess zu beschleunigen.
Abbildung 11: Voxelesierung der Figur [CLT08].
4.1.4 Effektspezifische Einflussgröße
Je nach verwendeten Effekt müssen noch weitere Größen gespeichert werden, die das
Fluid transportieren soll oder die Einfluss auf die Bewegung des Fluides haben. Jeder
dieser Größen wird durch ein Skalarfeld beschrieben. Die Advektion der einzelnen Werte
wird dabei gemäß
∂φ
= −(u · ∇)φ ,
(6)
∂t
vorgenommen. φ ist hierbei die Größe die transportiert werden soll.
Rauch hat beispielsweise in [CLT08] zwei zusätzliche Größen für Dichte und Temperatur.
Daher werden zwei weitere Skalarfeld — letztendlich Texturen — benötigt um diese zu
speichern. Soll nur eine Größe transportiert werden, so reicht es aus, sie mit Gleichung 6
zu berücksichtigen. Hat die Größe jedoch Einfluss auf die Bewegung des Fluids, wie die
Temperatur in diesem Beispiel, so muss diese noch als externe Kraft berücksichtigt werden. Dies wird hier durch die Auftriebskraft beschrieben, die als externe Kraft aufaddiert
wird. Der Effekt ist, dass kalter Rauch ab- und warmer aufsteigt.
Für Feuer wird noch eine Reaktionskoordinate transportiert. Diese beschreibt einfach
gesagt den Brennwert des Feuer an einer Position und wird in jedem Simulationsschritt
reduziert. Ist der der Wert 0 erreicht, so „erlischt“ das Feuer an dieser Position.
16
4.2 Rendern
Nach jedem Simulationsschritt steht nun ein veränderter Volumendatensatz zur Verfügung. Aus diesen Daten soll nun ein Bild generiert werden. Im zweiten Kapitel wurden
bereits mehrere Verfahren zum Volume-Rendern kurz vorgestellt. Crane et al. verwendeten in [CLT08] zum Rendern ein Raycasting-Verfahren, dass sich an dem von Westermann und Krüger in [KW03] vorgestellten Verfahren orientiert. Im Folgenden wird dieses
Verfahren vorgestellt.
Hierbei wird ausgehend vom Augpunkt mehrere Strahlen auf den Volumendatensatz
geschossen. Entlang des Strahls werden die Werte innerhalb des Datensatze akkumuliert
um so die Farbe für den Pixel zu bekommen. Hierfür muss bekannt sein, wo der Strahl
auf das Volumendatensatz auftrifft, in welche Richtung er diesen durchquert und wie
lang die Strecke des Strahls innerhalb des Volumens ist.
Dieser Prozess läuft in zwei Schritten ab. Der erste Schritt ist ein Vorverarbeitungsschritt,
um dem Eintrittspunkt und die Länge für jeden Strahl zu bestimmen. Diese Werte werden
in einer 2D-Textur abgespeichert, hier bezeichnet mit RayData. RayData hat dabei die
Ausmaße des Viewports. Der zweite Schritt ist der eigentliche Raycasting-Prozess, bei
dem der Volumendatensatz abgetastet wird.
4.2.1 Vorverarbeitung
Der Volumendatensatz wird zunächst in eine 3D-Textur geladen. Zu dieser 3D-Textur
wird nun ein Bounding-Volume erstellt, dass in der Szene platziert wird. Die Strahlänge
ist die Strecke zwischen Eintritts- und Austrittspunkt des Strahl im Bounding-Volume
(Abbildung 12). Der Eintrittspunkt ergibt sich aus der Texturkoordinate der Vorderseite
des Bounding-Volumes.
Abbildung 12: Querschntt des Bounding-Volumes
17
Nun wird als erstes die Rückseite des Bounding-Volumes gezeichnet. Ein Fragmentprogramm bestimme nun den Abstand (im View-Space) zwischen Augpunkt und Rückseite
und speichere diesen Wert im Alphakanal von RayData
RayData.alpha = length(Austrittspunkt − Augpunkt)
Danach wird die Vorderseite des Bounding-Volumes gezeichnet. Ein anderes Fragmentprogramm bestimmt nun den Abstand zwischen Augpunkt und Vorderseite sowie den
Eintrittspunkt. Der Eintrittspunkt ist dabei die Texturkoordinate des Bounding-Volumes.
Diese Werte werden auch in RayData geschrieben, bei aktivierter subtraktiver Farbmischung. Dies hat den Folgenden Effekt:
RayData.alpha = RayData.alpha − length(Eintrittspunkt − Augpunkt)
RayData.RGB = V orderseite.RGB
Nun befindet sich im RGBKanal von Raydata der Eintrittspunkt und im Alphakanal die
Länge des Strahls.
4.2.2 Raycasting
RayData enthält nun alle notwendigen Daten. Nun kann das Volumen mit dem Strahl
abgetastet werden. Die Richtung des Strahls ergibt sich dabei aus der Differenz zwischen
Eintrittspunkt und Augpunkt:
Strahlrichtung = RayData.RGB − Augpunkt
Ausgehend vom Eintrittspunkt entlang des Strahls werden nun die Volumendaten abgetastet, bis die maximale Anzahl der Abtastpunkte für diesen Strahl erreicht ist. In
[Crane2008] wurde die Anzahl so gewählt, dass der Abstand zwischen zwei Punkten die
halbe Voxelgröße hat.
Der Farbwert wird nun nach folgenden Schema entlang der Abtastpunkte akkumuliert:
RGBf inal + = RGBSample · AlphaSample · (1 − Alphaf inal )
Alphaf inal + = AlphaSample · (1 − Alphaf inal )
Hierbei handelt es sich um die Formel für Farbmischung von Vorne nach Hinten. Überschreitet Alphaf inal einen bestimmten Wert (z. B. Alphaf inal > 0.99), kann das Abtasten
für diesen Strahl abgebrochen werden, da dahinter liegende Objekte nicht mehr sichtbar
sind. Dieser Vorgang wird für jeden Strahls wiederholt.
18
4.3 Rauch und Feuer
Wie bei der Simulation bereits gesagt wurde, wird für den Raucheffekt ein Dichte- sowie ein Temperaturwert benötigt. Die Temperatur ist jedoch für die Farbgebung uninteressant. Die Farbgebung basiert ausschließlich auf der Dichte. Dieser wird bei der
Generierung der Fluidelement durch eine zeit- und zufallsabhängigen sinusförmige Funktion bestimmt. Außerdem wird noch ein Gaussfilter verwendet. Diese Prozedur ist nicht
physikalisch begründet, sondern sie liefert nur einen ausreichend guten Effekt von herumwirbelnden Rauch ( Abbildung 10). Eine Transferfunktion wird in diesem Fall nicht
verwendet, da die Farbe direkt aus der Dichte bestimmt werden kann.
Auch Feuer verfügt über eine Dichte die ähnlich wie beim Rauch gesetzt wird aber mit
Parametern. Der eigentliche Unterschied ist aber, dass für Feuer eine Reaktionkoordinate
verwendet wird dessen Bewegung durch
∂Y
= −(u · ∇)Y − k ,
∂t
(7)
beschrieben wird [NFJ02]. Y ist hierbei die Reaktionskoordinate und k der Wert, um dem
sie in jedem Simulationsschritt reduziert wird. Y wird nun über Transferfunktion (Lookup in einer 1D Textur) ein Farbwert zugewiesen. Dieser wird noch mit der Feuerdichte
vermischt und man erhält die endgültige Farbe. Solange Y einen Wert größer 0 hat, wird
Feuer gezeichnet. Hat der Wert jedoch 0 erreicht wird nur Rauch gezeichnet. Dadurch
erhält man einen feinen Übergang vom Feuer zum Rauch (Abbildung 13).
Abbildung 13: Gargoyle im brennenden Feuer. An der „Feuergrenze“ geht Feuer in dunklen
Rauch über
Natürlich ist abbilden von Y auf einen Farbwert eine starke Vereinfachung. Ein stärker
physikorientiertes Verfahren ist [NFJ02] zu entnehmen. Auch für den Rauch gibt es auf-
19
wenigere Verfahren [FSJ01]. Darin werden auch noch Self-Shadowing und Beleuchtung
besprochen.
4.3.1 Weitere Problemstellungen
Die bisherige Ausführung diente dazu um den groben Ablauf des Renderns zu verstehen.
Es gibt aber noch weitere Problemstellungen, auf die noch nicht eingegangen wurde.
Zunächst einmal sind beim Renderprozess noch keine Objekte berücksichtigt worden, die
innerhalb des Effekts sind oder ihn ganz oder teilweise verdecken. Abbildung 14 illustriert
die Situation.
Abbildung 14: Zwei Objekte (grün) im Effekt. Linkes Objekt verdeckt die Vorderseite,
Rechtes ist vom Effekt umschlossen [CLT08].
Um dies zu berücksichtigen, muss der Renderprozess um zwei Schritte ergänzt werden.
Zunächst einmal wird bei der Bestimmung der Länge des Strahls nicht mehr der Abstand
vom Augpunkt zur Rückseite des Bounding-Volumes genommen, sondern das Minimum
von Szeneabstand und Abstand zur Rückseite (Gleichung 8).
RayData.alpha = min(AbstandSzene , AbstandRueckseite )
(8)
Um Festzustellen, ob ein Objekt vor dem Effekt ist, wird überprüft, ob Szenedistanz kleiner ist als der Abstand zur Vorderseite. Ist dies der Fall, so wird ein Teil der Vorderseite
durch ein Objekt verdeckt. Um dies in der RayData zu vermerken, wird ein negativer
Wert in den roten Farbkanal (x-Koordinate Eintrittspunkt) geschrieben. Beim Raycasting wird dann überprüft ob die x-Koordinate des Eintrittspunktes negativ ist. Sollte
dies der Fall sein, wird der Vorgang für diesen Strahl abgebrochen.
Ein weiteres Problem, das auch noch nicht berücksichtigt wird, ist wenn der Vorderseite
des Bounding-Volumes nicht oder nur teilweise gezeichnet wird. Dies ist dann der Fall,
wenn der Augpunkt innerhalb des Effektes liegt oder so nah an ihm dran ist, dass die
Near-Clipping-Plane ein Teil der Vorderseite abschneidet (Abbildung 15). Mit dem bisherigen Verfahren ist es so nicht mehr möglich, den Eintrittspunkt und somit auch nicht
die Strahlrichtung zu bestimmen.
20
Abbildung 15: Near-Clipping-Plane schneide das Bounding-Volume so, dass der mittlere
Bereich im Inneren und der Randbereich außerhalb liegt [CLT08].
Um das zu berücksichtigen, wird für jedes Pixel, bei dem nur die Rückseite aber nicht
die Vorderseite gezeichnet wird, ein negativer Grünwert an der entsprechenden Position
in RayData geschrieben. Dies geschieht beim Rendern der Rückseite im Vorverarbeitungsschritt, wo bisher nur der Abstand zur Rückseite gesetzt wurde. Beim Setzen der
Eintrittspunkte in RayData wird der negative Grünwert nur an Stellen überschrieben, wo
auch die Vorderseite gezeichnet wird. Beim Raycasting wird nun geprüft, ob der Grünwert negativ ist. Ist dies der Fall, dann wird der RGB-Wert für diesen Pixel durch die
Position der Near-Clipping-Plane im Texturraum des Bounding-Volumen ersetzt. Außerdem wird der Distanzewert um den Abstand von Augpunkt und Near-Clipping-Plane
verringert werden.
4.3.2 Artefakte
Es können eine Reihe von Artefakten beim Rendern von Volumen-Daten entstehen. Das
bekannteste ist wohl der „Lego-Effekt“ (Abbildung 16). Ein weiterer ist das Banding, ein
Treppeneffekt im Farbverlauf.
Abbildung 16: Lego-Effekt durch die Würfelstruktur [htt09].
21
Es gibt eine Reihe von Ansätzen die diese Probleme behandeln. Hier gehören unter anderem Filterung, Jittering, Erhöhung der Abtastfrequenz oder eine Kombination daraus
[CLT08].
22
5 Vergleich zu Partikelsystemen
Wie bereits weiter oben erwähnt, stehen Partikelsysteme in Konkurrenz zu den volumenbasierten Ansätzen. In diesem Abschnitt werden nun die Partikelsysteme mit den
volumenbasierten Ansatz verglichen. Bevor dies allerdings gemacht wird, wird zunächst
noch das grundlegende Prinzip der Partikelsysteme erklärt.
Partikelsysteme basieren bis heute im Wesentlichen alle auf dem von Reevse in [Reeves1983] vorgestellten Verfahren. Hierbei wird von einem logischen Partikel ausgegangen,
das ein Platzhalter für ein zu zeichnendes Objekt ist. Das Objekt kann dabei sehr einfach
sein (z.B. Punkt mit Farbe) oder auch ein komplexes Modell. Die Erzeugung, Bewegung
und Lebensdauer dieser Partikel wird dabei vom einem Partikelsystem bestimmt.
Ein Partikel verfügt über mehrere Attribute. Diese können prinzipiell beliebig festgelegt
werden. Überlicherweise verfügen diese jedoch über eine Position, Geschwindigkeit, Alter/Lebensdauer, Farbe, Größe und Form [Reeves1983]. Außerdem können Partikel auch
Partikelsysteme repräsentieren (hierarchische Partikelsysteme).
Für die Erzeugung der Partikel und Positionierung des Partikelsystems ist der Emitter
zuständig. Diese markieren den Ursprung der Partikel. In der Regel wird dieser eine einfache Form sein, wie zum Beispiel ein Rechteck, das den Bereich festlegt in dem die Partikel
entstehen können. Nach der Erzeugung müssen die Partikel in jedem Simulationsschritt
bewegt werden. Das Schema hierfür kann beliebig einfach oder komplex sein, angefangen von einem zufälligen Bewegungsmuster bis hin zu einer physikbasierten Simulation.
Ist die maximale Lebensdauer erreicht oder hat sich das Partikel zu weit vom Emitter
entfernt, so wird das Partikel aus dem System wieder entfernt. Die Visualisierung der
Partikel wird mit dem klassischen oberflächenbasierten Rendern realisiert. Die Partikel
werden durch Grafikprimitive oder Billboards ersetzt und an die Grafikkarte zum Zeichnen übergeben. Je nachdem was das Partikel repräsentiert und wie es sich bewegt können
unterschiedliche Effekte erzeugt werden (Abbildung 17).
Abbildung 17: Visualisierung der Partikel als Partikel (links) und als Fäden (rechts)
[Wik09a].
23
Bis zur Simulation scheint der volumenbasierte Ansatz keinen Vorteil gegenüber dem
Partikelsystem zu haben. Die Simulation der Partikel eines Partikelsystems kann auch in
einem Voxelgitter stattfinden. Im Gegensatz zu den Partikelsystemen ist der volumenbasierte Ansatz jedoch auf die dreidimensionale Gitterstruktur angewiesen. Partikelsysteme
sind zunächst einmal unabhängig von einer derartigen Struktur. Partikel können so theoretisch mit Objekten der Umwelt, an beliebiger Stelle, interagieren. Das Fluid hingegen
nur mit Objekten, die sich innerhalb des Voxelgitters befinden. Jedoch sind viele physikbasierten Simulationen — wie auch die oben vorgestellte Strömungssimulation — auf eine
zwei oder dreidimensionale Gitterstruktur angewiesen [LOj09]. Nutzt ein Partikelsystem
eine derartige Simulation, so gilt diese Einschränkung auch für diese.
Die Hauptunterschiede zeigen sich zweifellos beim Rendern, da hier zwei grundsätzlich verschiedene Verfahren verwendet werden. Partikelsysteme greifen auf das klassische
oberflächenbasiertes Rendern zurück, wohingegen der volumenbasierte Ansatz auf Verfahren des Volume-Renderings zurückgreift. Letztere werden in der Regel nicht nativ von
der Grafikkarte unterstützt. Diese können jedoch inzwischen oft mit Shader-Programmen
realisiert werden, die diesen Prozess unterstützen. Es gibt mehrere Visualisierungsmethoden beim Volume-Rendering (siehe Abschnitt 2). Je nach Anwendung kann somit ein
Verfahren gewählt werden, dass das beste Ergebnis liefert.
Die optische Qualität zwischen den beiden Ansätzen ist schwer zu beurteilen. Beide Ansätze sind in der Lage sehr gute wie auch sehr schlechte Ergebnisse zu liefern. Das ganze
ist von der Anwendung abhängig. Der voxelbasierte Ansatz hat jedoch große Vorteile,
wenn es darum geht physikalische Größen bei der Farbbildung zu berücksichtigen. Feuer
zum Beispiel wirkt bei Partielsystemen immer wie brennender Rauch (Abbildung 18 c)).
Auch wenn die Bewegung selbst gut aussieht so fehlt irgendwie die Flammenbildung.
Diese kann zwar recht gut mit Videotexturen verbessert werden Abbildung 18 a) und b)
[Ngu04], jedoch ist es nicht oder nur schwer möglich, Größen wie Temperatur, Dichte,
Brennwert die direkt Einfluss auf das Erscheinungsbild einer Flamme haben können zu
berücksichtigen. Der voxelbasierte Ansatz kann dies, durch den Schritt über die Transferfunktion (Abbildung 18 d)).
Volumenbasierte Ansätze haben, bedingt durch die Volumenstruktur, einen hohen Speicherbedarf (O(n3 )). Zwar lässt sich dies durch entsprechende Datenstrukturen verbessern,
dennoch bleibt die kubische Komplexität ein Problem. Tabelle 1 zeigt des Speicherbedarf aus dem oben vorgestellten Verfahren. Eine Aufstellung, wie diese Werte genau
zustande kommen, ist aus [CLT08] zu entnehmen.
Fluidsimulation
32 bytes / Voxel
Voxelisierung
9 Bytes / Voxel
Rendering
20 Bytes / Pixel
Tabelle 1: Speicherbedarf
Ausgehend von dem Beispiel in Abbildung 9 links, mit einer Gittergröße von 128x64x64
(= 524.288 Voxel) bei einer Auflösung von 1920 x 1080 Pixel kommt man so auf einen
24
(a)
(b)
(c)
(d)
Abbildung 18: a) zeigt Feuer das mit der in b) gezeigten Textursequenz erzeugt wurde
[Ngu04]. c) Feuer mit 5000 Partikeln [Ngu04]. d) Feuer mit einem physikbasieten Ansatz. Gittergröße: 160x160x160 [NFJ02]
25
Speicherbedarf von
(32Bytes + 9Bytes) · 524288 + (1920 · 1080) · 20Bytes = 62967808Bytes ≈ 63M B.
Bei einer Verdoppelung der Gittergröße auf 256x128x128 (= 4.194.304 Voxel) sind es
schon
(32Bytes + 9Bytes) · 4194304 + (1920 · 1080) · 20Bytes = 213438464Bytes ≈ 214M B.
Der Speicherbedarf bei Partikelsystemen wächst hier hingegen nur linear mit Anzahl der
Partikel.
Generell scheinen Anwendungsmöglichkeiten von Partikelsystem wesentlich größer zu
sein. Sie beschränken sich nicht nur auf formverändernde Effekte wie Feuer oder Rauch,
sondern können auch zur Simulation von Haaren, Pflanzen oder Textilien eingesetzt werden (Abbildung 17 rechts). Auch bei Effekten, bei denen die Partikel nicht nur als Gesamteffekt, sondern auch einzeln wahrnehmbar sein sollen, wie zum Beispiel herumfliegende
Trümmer bei einer Explosion oder Regentropfen bei einem Regenschauer, eignen sich
die Partikelsysteme besser. Volumenbasierte Ansätze eignen sich für Anwendungen, bei
denen physikorientiertes Rendern wichtig ist.
26
6 Zusammenfassung
In dieser Arbeit wurde ein Verfahren zum Visualisieren von volumetrischen Effekten
durch Volumen-Rendering vorgestellt. Hierbei wurde eine Reihe von gängigen Verfahren
vorgestellt, mit denen Volumendaten visualisiert werden können. Der Hauptteil dieser Arbeit beschäftigte sich damit ein Verfahren von Crane et al. [CLT08] vorzustellen. Hierbei
wurde ein Strömungsmodell verwendet, um die Simulation des Effektes in einem Voxelgitter durchzuführen. Zum Render des Volumendatensatzes wurde ein Raycasting Ansatz
von [KW03] verwendet. Sowohl die Simulation als auch das Raycasting können komplett
auf der Grafikkarte durchgeführt werden. Zum Schluss wurde noch ein Vergleich mit den
Partikelsystem gemacht und versucht, so die Vor- und Nachteile des volumenbasierten
Ansatzes herauszuarbeiten.
Es setzte sich der Eindruck durch, dass wenn ein Effekt benötigt wird, bei dem Partikel als einzelne Objekte wahrnehmbar sein sollen (z. B. Regentopfen), dann ist das
Partikelsystem die bessere Wahl. Soll jedoch eine Simulation verwendet werden, die eine
Gitterstruktur benötigt, ist der volumenbasierte Ansatz sinnvoller. Natürlich sind auch
hybride Ansätze denkbar. Durch immer leistungsfähigere Computer und Grafikkarten, sowie der steigenden Menge an Arbeitsspeicher, scheint in der Spieleindustrie das Interesse
an Voxel-Engines wieder zu steigen [Ber09], was auch für den Einsatz der volumenbasierten Verfahren spricht.
27
Literatur
[AS09]
Ament, Marco und Wolfgang Straßer: Dynamic Grid Refinement for
Fluid Simulations on Parallel Graphics Architectures. In: Eurographics 2009,
2009.
[Ber09]
Bertuch, Manfred: Klötzchenwelten. c’t, (4), 2009.
[c09]
c: Marching Cubes. http://de.wikipedia.org/wiki/Marching_Cubes, 2009.
(Letzter Zugriff 27.06.2009).
[CLT08]
Crane, Keenan, Ignacio Llamas und Sarah Tariq: Real-Time Simulation and Rendering of 3D Fluids. In: GPU Gems 3. Addison-Wesley, 2008.
[FSJ01]
Fedkiw, Ronald, Jos Stam und Henrik W. Jensen: Visual Simulation
of Smoke. In: SIGGRAPH 2001, 2001.
[Har04]
Harris, Mark J.: Fast Fluid Dynamics Simulation on the GPU. In: GPU
Gems 1. Addison-Wesley, 2004.
[htt09]
http://en.wikipedia.org/wiki/Voxel: Voxel. http://en.wikipedia.
org/wiki/Voxel, 2009. (Letzter Zugriff 29.06.2009).
[IKLH04] Ikits, Milan, Joe Kniss, Aaron Lefohn und Charles Hansen: Volume
Rendering Techniques. In: GPU Gems 1. Addison-Wesley, 2004.
[KW03]
Krüger, Jens und Rüdiger Westermann: Acceleration Techniques for
GPU-based Volume Rendering. In: IEEE Visualization 2003, 2003.
[LOj09]
Laurien, Eckart und Herbert Ortel jr.: Numerische Strömungsmechanik. Vieweg + Teubner, 2009.
[NFJ02]
Nguyen, Duc Q., Ronald Fedkiw und Henrik W. Jensen: Physically
Based Modeling and Animation of Fire. In: SIGGRAPH 2002, 2002.
[Ngu04]
Nguyen, Hubert: Fire in the "Vulcan"Demo. In: GPU Gems 1. AddisonWesley, 2004.
[Nvi]
Nvidia: CUDA Zone – The resource for CUDA developers. http://www.
nvidia.com/object/cuda_home.html. (Letzter Zugriff 27.06.2009).
[Sta99]
Stam, Jos: Stable Fluids. In: SIGGRAPH 99, 1999.
[Wat00]
Watt, Alan: 3D Computer Graphics, Kapitel 13. Addison-Wesley, 2000.
[Wes90]
Westover, Lee: Footprint evaluation for volume rendering. In: SIGGRAPH
90. ACM, 1990.
[Wik09a] Wikipedia: Particle system. http://en.wikipedia.org/wiki/Particle_
system, 2009. (Letzter Zugriff 24.06.2009).
28
[Wik09b] Wikipedia:
Partikelsystem.
http://de.wikipedia.org/wiki/
Partikelsystem, 2009. (Letzter Zugriff 29.06.2009).
[Wik09c] Wikipedia: Schwarzer Körper.
http://de.wikipedia.org/wiki/
Schwarzer_K%C3%B6rper, 2009. (Letzter Zugriff 29.06.2009).
[WW92] Watt, Alan und Mark Watt: Advanced Animation and Rendering Techniques – Theory and Practice, Kapitel 13. Addison-Wesley, 1992.
29