2016-07-09 23 views
2

Ich arbeite an meiner ersten Game-Engine und versuche, ein GPU-Partikelsystem zu implementieren. Ich habe bereits eine auf der CPU implementiert, aber jetzt versuche ich, sie effizienter zu machen. Mein Problem ist im Speziellen das Laichen von Partikeln auf Lebenszeit.Erstelle GPU-Partikel

Da ich mit Framebuffer-Texturen für die Partikel-Engine arbeite, ist es sehr parallel, aber auf Kosten von nicht in der Lage, zur CPU zurückzukehren, nicht wahr? Ich habe einen ersten Durchlauf beim Zeichnen eines Quads, das die Berechnungen für dieses spezielle Partikelsystem behandelt (es wird wahrscheinlich ein zweites Quad zum Sortieren geben müssen), und dann führe ich eine Idee aus, die ich hatte einen booleschen Wert oder einen int zu verwenden, wenn ich ein Partikel erstellen muss, das entweder die Notwendigkeit darstellt, ein Partikel zu erzeugen, oder die Menge der zu erzeugenden Partikel, die beide von der CPU initialisiert werden. Wenn ich also ein Teilchen (Pixel) finde, das lebenslang ist (sagen wir der Alpha-Wert der ersten fbo-Textur), ist es kleiner als Null, und ich weiß, dass ich es erstellen soll. Wie deaktiviere ich die Kreation für den Rest der Partikel oder verringern Sie die Anzahl der zu platzenden Partikel? Ich habe von Dingen wie der Umwandlung von Feedback gehört, aber ich weiß nicht, ob das der beste Weg ist. Und staatenlose Teilchen sind limitierend - nicht alle Teilchen haben eine Laichrate von 1: 1.

Um die Frage kurz zu wiederholen: Was ist der beste Weg, um GPU-Partikel zu spawnen?

Wenn ich die Anzahl der Partikel auf der CPU haben könnte, könnte ich übrigens die Menge in glDrawArraysInstanced zeichnen, also wenn Sie das in Ihre Antwort aufnehmen könnten, wäre ich dankbar.

+2

"Ich arbeite an meiner ersten Spiel-Engine" - [Spiele schreiben, nicht Engines] (http://geometrian.com/programming/tutorials/write-games-not-engines/) –

+1

Ich habe gearbeitet Spiele vorher. Müde von den Engines anderer Leute zu sein und nicht für jedes Spiel eine komplett neue Codebase schreiben zu wollen. Ich habe bereits eine Menge Arbeit an Rendering, Physik, Beleuchtung, Input und Tonnen anderer Systeme geleistet. Das Stoppen hört sich momentan nicht nach einer guten Idee an. –

+1

Oh, und @JesperJuhl - Ich habe gerade den Artikel gelesen. Ich habe bereits einige Spielideen geplant, und jedes einzelne System im Code soll unter verschiedenen Arten von Spielen funktionieren. Wenn ich ein Spiel kodiere, wäre es nicht sehr flexibel. Mein Eingabesystem zum Beispiel ist kompatibel mit Linux und Windows, und bald Mac, sowie entworfen, um mit verschiedenen Eingängen und Funktionen zu funktionieren, um einfach zu bedienen und flexibel zu sein.Also danke für die harte Liebe, aber ich brauche sie nicht wirklich - ich muss nur die beste (und flexibelste) Lösung finden, um dieses Problem zu lösen. –

Antwort

0

Ich werde mal ran ...

Die CPU sollte wissen, was die maximale Anzahl der Teilchen ist und die aktuelle Anzahl der ‚live‘ Teilchen (die die Poolgröße wird). Die erste Zahl wird verwendet, um die VBOs des Partikelzustands zu initialisieren oder ihre Größe zu ändern, und sollte sich nicht oft ändern. Die zweite kann Frame für Frame ändern, wenn Sie möchten.

Die individuellen Partikellebensdauern sollten als Teil der VBO-Werte gespeichert werden. Vermutlich verwenden Sie einen Zähler oder einen Zeitwert, um Position, Farbe usw. zu bestimmen. Wenn dieser Zähler ein Maximum erreicht, "töten" Sie das Partikel und weisen es erneut zu. Durch Variieren der anfänglichen Zählerwerte müssen die Partikel nicht alle identisch starten und aktualisieren.

Für die Aktualisierung des Partikelzustands möchten Sie die Rückmeldung der Transformation. Sie haben einen 'Vertex-Shader', der neue Werte für jedes Partikel von alt berechnet und diese in einen anderen VBO schreibt. Details und Beispielcode finden Sie im OpenGL-SuperBible. Ich ping-pong zwischen zwei VBOs, eins für alte Werte, eins für neu, aber Sie könnten auch beschließen, Texture Buffer Objects zu verwenden, die große Arrays (viel größer als uniform) sind, in die Sie innerhalb von Shadern schreiben können. Die Anzahl der Partikel, die jedes Mal aktualisiert werden, wird vom CPU-Live-Zähler gesteuert.

Hoffe, das hilft.

+0

Vielen Dank für Ihre Antwort, aber während ich über die Verwendung von VBOs nachdachte, entschied ich mich dagegen. Ich dachte Textur (wie diese http://nullprogram.com/blog/2014/06/29/) wäre eine bessere Lösung für eine große Anzahl von Partikeln. Meine Partikel haben derzeit eine Lebenszeit im Loop, aber ich möchte, dass sie für ein bisschen "sterben" können, und das ist mein Problem. Ich kann nicht genau ein neues Partikel auf der GPU erstellen. –

+0

Wenn Sie eine effiziente Parallelverarbeitung durchführen wollen, denken Sie NICHT an die Kontrolle einzelner Partikel. Sie brauchen Algorithmen, die über große Zahlen hinweg funktionieren. Einzelne Partikel können für ein bisschen "sterben", indem sie entweder die Anzahl der in glDrawArraysInstanced verwendeten Lebewesen reduzieren oder indem sie zulassen, dass Partikel ein negatives Alter haben und unsichtbar sind, bis das Alter> 0 –

+0

genau mein Plan ist, mein Problem ist bei der Implementierung . Aufgrund der zufälligen Lebensdauer der Partikel wird es schwierig sein, die Anzahl der Partikel zu steuern, die für den GlidrawarrayInstanced aber zusätzlich vorhanden sind. Wenn ich die Anzahl der Partikel habe, die auf der GPU inkrementiert und dekrementiert wird, kann ich dieses Problem lösen. –