GLSL Partikel
Bitte haben Sie etwas Geduld und nehmen Sie keine Änderungen vor, bis der Artikel hochgeladen wurde. |
Einleitung
So mal wieder was schreiben wo von ich keine Ahnung hab...
Sicher habt die meisten zumindest schon mal von Partikelsystemen gehöhrt. Da die Leistung der Grafikkarten in den letzten Jahren immer größer wurde und auch die Flexibilität immer größer wurde liegt es nahe ein Partikelssystem direkt in GLSL zu programieren. Dadurch, dass keine Daten mehr zu der Grafikkarte transportiert werden müssen und die CPU von den Berechnungen entlastet wird, sollten um eine Größenordnung mehr Partikel möglich sein.
Im gegensatz zu den klassischen Partikelsystemen wo alle Partikel unabhängig von einander sind, gibt es auch Partikelsysteme, bei denen Partikel mit einander verbunden sind. Dazu gehöhren unter anderem auch Seile und Kleidung. Der übergang zu echten Physiksimulation ist fließend. Der wahrscheilich größte unterschied ist, das ein Partikelsystem nur ein grafischer Effekt ist und keinen Einfluss auf die restliche Physik nimmt.
Grundlagen für die Implementierung
Wärend es bei konventionellen Partikelsystemen am sinvollsten war, die berechneten Daten per VBO oder Vertexarray in die Grafikkarte zu laden. Müssen bei einem GLSL-Partikelsystem, alle Daten in Texturen gespeichert werden. Da die GPU in der Lage ist mehr als die 10fache Menge an Partikeln zu verabeiten und außer den Positionen noch Physikdaten gespeichtert werden müssen, muss von Anfang an der Speicherkonsum auf der Grafikkarte mit geplant werden. Die Anzahl der Komponenten sollte sich möglicherweise durch vier teilen lassen. Zudem sollte beim Speichern stat float32 möglichst nur float16 genutzt werden. Ein Beispiel wäre ein einfaches Partikelsystem: Für drei Positionskomponenten, eine Zeitkomponente, drei Geschwindigkeitskomponenten und eine noch freie Komponente z.B. für Masse, werden 8 Werte benötigt. Bei einer Verwendung von float16 und 2^20 Partikeln, werden ganze 16MB GPU Ram verbraucht. Da es nicht möglich oder sinvoll ist in eine aktive Textur zu schreiben, wird eine zweite Textur benötigt, die die selbe Größe hat. So verbraucht unser Partikelsystem 32 MB GPU Ram. Da immer zwischen diesen zwei Buffern hin und hergerendert wird, spricht mach auch von einem Ping-Pongbuffer.
Damit keine getrennten Buffer für Position und Geschwindigkeit verwendet werden müssen, sollten Multiplerendertargets verwendet werden. Diese sind nicht schwerer zu verwenden als normale Frambufferobjekte. Eine Einschränkung ist, dass nur Rendertargets mit gleichen Bitanzahlen kombiniert werden können. So lässt sich ein 1x float32 mit einem 2x float16 und einem RGBA8 Rendertarget kombinieren. Ein RGBA_float16 Target z.B. lässt sich nur mit einem RG_float32 und sich selbst kombinieren.
Weiterhin ist es sehr sinvoll einen float16 Frambuffer zu verwenden, da so nachträglich durch die Blende die Helligkeit des Bildes optimal angepasst werden kann (Siehe fehlendes HDR tutorial....)
Nun erst einmal ein Program im Pseudocode um einen Überblick über die Initialisierung zu schaffen:
Optional (3 Zeilen): Eine RGB_Float16 Textur für HDR Rendering mit der OpenGLauflösung erzeugen. Ein Rendebufferobjekt für den Z-Buffer erstellen. Beides zu einem Frambufferobjekt hinzufügen. 2x2 RGBA_Float16 Texturen mit 1024x1024 erstellen. 2 mit initialisierungsdaten füllen Ein weiteres Frambufferobjekt erzeugen und die zwei übrigen daran binden. Laden weitere Texturen Shader Laden Haupschleife Aktivieren des Partikelphysikshaders und des Rendertargets Rendern der Physikdaten in den zweiten Buffer Buffer tauschen. Die gerderten Daten in ein VBO übertragen oder später per Vertexttexturefetch nutzen. Nortmales Rendertaget auswählen Rest der Scene Rendern Partikel mit Partikelshader als Pointsprites rendern.