making of 1 million particles

this time I will give you some insights on how to create a gpu driven particle system with opengl and glsl. for most of my opengl work I choose cinder and highly recommend to get in touch with it. already knowing cinder is not essential but gives a better understanding of the text. also since this is just a making of, not a step by step guide, some OpenGL and shader knowledge is required.

1mp_bw

before we dive into the code I think it’s good to get an overview on how the system works. the base of this particle system is a so called ping-pong framebuffer object. ping-pong means that you have two framebuffer objects (fbo) which are drawn alternately. when fbo A is drawn fbo B is used for calculations. on the next frame B will be drawn and A is used for calculations and so on. the particle movement is calculated by an glsl shader, all results (current position, velocity,…) are saved into textures. the drawing of the particles is also controlled by a shader who controls opacity and size. each particle has a time to live, if it’s old enough it will be respawned at a new position with it’s initial velocity. you see there is not that much going on, so now let’s look at the code a little bit deeper!

get some more…

1 million particles revisited

1million particles

here we go again, I reworked my gpgpu particle system which I did some time ago (link). the new version offers a better particle movement driven by perlin noise. also it is a bit more colorful since the original version was black & white only. aside from some minor code tweaks the big thing is that you can grab a copy on github now! i’ve got some requests to share the code but never felt that it is good enough to give it to others (the new version might not be that better… ;-) ). i hope it will help people to learn something about gpgpu programming and OpenGL in general :-) at the moment I am also writing a “making of” to explain some of the nifty stuff a bit more, so check the blog the next days!

github

Reach for the million…

Mein neuestes Projekt ist nun mehr oder weniger abgeschlossen. Ziel war ein Partikelsystem, welches komplett auf GPU Basis agiert. Das bedeutet, dass das komplette Partikelsystem über GLSL Shader gesteuert wird, der C++ Code dient nur als Rahmenwerk zur Anwendungserstellung und Initialisierung aller benötigten Teile.

Auf meinem MacBook Pro (late 08), in dem eine Geforce 9600M GT schlummert, schaffe ich mit 1.048.576 Partikeln immerhin 29 Frames pro Sekunde, der PC mit einer Geforce 250GT sogar 60 Frames. Das ist ein ziemlich beeindruckendes Resultat bezüglich GPGPU Programmierung wenn ich daran denke, dass mein altes Partikelsystem (CPU) schon bei ca. 25.000 Partikeln mächtig einbrach.

Die Basis des Systems ist ein Ping-Pong Framebuffer, also zwei Framebuffer, aus denen abwechselnd gelesen und geschrieben wird. Beim Anwendungsstart werden zudem vier Texturen erstellt welche die Initialisierungswerte für die Partikeleigenschaften (Positionen, Geschwindigkeiten, Alter, Masse,…) und das Vektorfeld beinhalten. Das Vektorfeld lässt die Partikel um den Koordinatenursprung rotieren (link) und wird nach der Initialisierung nicht mehr verändert. Zusätzlich wird aber noch ein “Dummy” Vertex Buffer Object benötigt, welches genauso viele Punkte beinhalten muss, wie das Partikelsystem anzeigt. Ansonsten beschränkt sich die cinder App darauf, Tastatur- und Mausereignisse abzufangen und den üblichen Kram zu erledigen.

Herz des Ganzen ist ein Fragment Shader, welcher die Berechnung der Geschwindigkeiten und Positionen der Partikel übernimmt. Der Shadercode ist bisher jedoch ziemlich einfach, außer den Zugriffen auf die Texturen, den (einfachen) Berechnungen und dem Erstellen neuer Texturen passiert hier nicht viel. Ein Ziel für die Zukunft wäre natürlich noch komplexere physikalische Vorgänge wie Bewegungen in Galaxien oder Flüssigkeiten zu simulieren, für dass Herantasten an die Thematik soll es jedoch genügen.

Der zweite Shader dient nur der Darstellung der Partikel, hier werden abhängig vom Alter die Größe und Sichtbarkeit eines Partikels definiert. Mit wenigen Anpassungen kann man aber auch hier interessante Resultate erzielen, wie zum Beispiel das Einfärben eines Partikels bezüglich seines Ortes…

Zum Abschluss bleibt zu sagen, dass GPGPU Programmierung ein Riesen Spaß ist, auch wenn der Einstieg einiges fordert. Das nächste Projekt wird sich wieder mit der Kinect beschäftigen und dann geht auch bald die Diplomarbeit los, also wie immer…stay tuned!