Partikelsystem für eigenes Spiel

Crysis nerd

Freizeitschrauber(in)
Partikelsystem für eigenes Spiel

Guten Tag,

ich habe gerade angefangen für ein Spiel, an dem ein Kumpel und ich programmieren, ein Partikelsystem zu bauen. Das Spiel ist 2D also kann es sich erstmal auf diese beiden Dimensionen beschränken.
Warum ich diesen Thread aufmache? Ich wollte einfach mal ein bischen berichten und von euch hören, ob ihr sowas schonmal gemacht habt. Und wenn: Ob ihr Tipps habt.

Ich habe zum Glück mal ein bischen in 3Ds Max mit Partikeln gearbeitet, also kenn ich zumindest die Grundlagen.
Zurzeit baue ich eine kleine Klasse für Partikel und eine Klasse für einen Partikelemitter. Also bis jetzt gibt es noch nichts vorzuzeigen, weil ich gerade erst angefangen habe ;) Aber falls ich was hinkriege, werd ich das hier eventuell posten. Denn wie der Threadersteller im Thread "Spiel Universe" schon gesagt hat: Wenn man hier etwas postet, bleibt man eher motiviert und dabei :P

Außerdem wollt ich mal fragen ob jemand sich von euch mit DirectX Instanzierung auskennt. Also wo man mehrere ähnliche Objekte in einem RenderCall rendern lässt. Gerade für Partikelsysteme ist das natürlich perfekt, um Performance zu sparen.

Naja so weit erstmal. Ich werde weiter berichten ..

mfg
Lukas
 
AW: Partikelsystem für eigenes Spiel

Naja so schwer ist das nicht, wenn man eine ordentliche Struktur rein bringt. Bei mir ist das ganze System z.B. so aufgebaut:
- class BaseEmitter: Basisklasse für alle Emitter (da kommen die Partikel raus). Die Klasse verfügt über eine virtuelle Methode namens "Fill", die eine Liste als Parameter bekommt. Was genau die Methode macht muss ich ja jetzt wohl nicht genau erklären, das sagt ja praktisch schon der Name. Diese Klasse muss dann noch alle Startparameter für die Partikel speichern.
- class BaseAffector: Basisklasse für alle Affektoren (die beeinflussen die Partikel, z.B. durch Gravitation/allg. Kräfte). Diese Klasse verfügt über eine Methode "Update", die ebenfalls wieder die Partikelliste als Parameter bekommt. In der Methode werden dann alle Partikel durchgegangen und entsprechend beeinflusst (z.B. ändert sich Geschwindigkeit, Beschleunigung etc.).
- class ParticleSystem: Dort läuft alles zusammen. Man kann mit der Methode "AddAffector" die oben erwähnte Klasseninstanz zu einer Liste hinzufügen, die dann in der Methode "Update" auf alle Partikel angewendet wird (evtl. in einem separaten Thread) (per BaseAffector->Update(...)). Man fügt Partikel hinzu, indem man "Particlesystem->Fill(BaseEmitter, int Anzahl)" aufruft.
- class Particle: Einfache Klasse, die lediglich ein paar Variablen wie Velocity, Acceleration etc. beeinhaltet.

So, ich hoffe das war verständlich ausgedrückt.^^
Man kann das ganze jetzt noch beliebig erweitern, indem man z.B. noch Kollisionserkennung hinzufügt bzw. Bereiche, von denen die Partikel z.B. abprallen.

Was das Instancing angeht: Im DX SDK gibts da 2 Beispiele, einmal für DX 9.0c und einmal für DX10. Ich denke allerdings, dass es vorerst auch ein einfacher Vertex Buffer tut.

Lg
 
AW: Partikelsystem für eigenes Spiel

Naja so schwer ist das nicht, wenn man eine ordentliche Struktur rein bringt. Bei mir ist das ganze System z.B. so aufgebaut:
So ähnlich habe ich dsa ganze auch aufgebaut. Ich bin zu meinem Erstaunen recht schnell voran gekommen, aber hab natürlich noch nicht alles. Also Particle und ParticleEmitter habe ich als Klassen. Natürlich brauch ich nachher noch eine Verwaltungsklasse, die alle Emitter verwaltet.
Das mit den Affectoren ist aber eine gute Idee. Da muss ich mir echt noch überlegen wie ich das mache... Hab mir zb. vorgestellt, dass für ein Nebel ein "chaos" affektor eingeführt wird. Also dass die Partikel so zufällig ein bisschen rumwabern. Nur bis jetzt hab ich noch kein tolles System gefunden, wie ich dsa mache. Aber die Idee eine komplette Affektor klasse zu machen is gut...


Was das Instancing angeht: Im DX SDK gibts da 2 Beispiele, einmal für DX 9.0c und einmal für DX10. Ich denke allerdings, dass es vorerst auch ein einfacher Vertex Buffer tut.
Mh jagut, ich hab nur gehört, dass die Performance stark zunimmt durch eine solche Technik. Ich versteh aber auch noch nicht ganz, wie das jetzt funktioniert mit dem Instancing.. Vorallem was DX10 mehr kann.
Aber zurzeit haben wir (also mein "engine-kumpel" und ich) ne recht ineffiziente methode glaub ich...
Aber mal sehne

Nächster Schritt ist für mich erstmal das ganze System schön abrunden, aufräumen und gut in die Engine integrieren... das wird ne arbeit -.-
 
AW: Partikelsystem für eigenes Spiel

Soweit ich das verstanden habe ist Instancing einfach das einsparen der ständigen Datenabfragen für Objekte, sprich wenn du eine Szene mit 100 Steinen hast, dann muss für jeden Stein das Drawing gemacht werden, also 100x und je nach Effizienz des Codes kann das dann Performance kosten.
Und beim Instancing wird .... ich dachte jetzt nach dem ersten Draw eines "geinstancten" Objektes gleich das alles mit den gerade vorhandenen Daten für den Rest der Objekte auch gleich durchgeführt ... jedenfalls werden dort die vorhandenen Infromationen genutzt und nicht 100x die eigentlich gleichen Daten von irgendwo abgerufen.
Aber genau weiß ichs auch nicht, die ganzen Bücher hier meinen immer Instancing ist zwar toll, aber auch wieder nicht sooo toll, als das man es gleich vom Anfang eines Buches benutzt ^^

Bei mehr mehr .... mehr Interesse :D -> PN
PS: DX? OpenGL? ...?
 
AW: Partikelsystem für eigenes Spiel

Direct X
Also zurzeit nutzen wir, scheinbar wie mir gesagt wurde, für jeden Partikel einen einzelnen vertex und index buffer.
Das is nicht soo tolle ^.^
Aber zurzeit macht mir sowieso fast mehr die CPU auslastung Sorgen, als die GPU. Die Update funktion der Partikel ist zwar recht klein und auch keine komplexen Operationen.. aber trotzdem, wenn ich mir das überlege, dass da eventuell noch Kollisionsabfrage rein soll.. böse für die CPU. Und ASM kann keiner von uns..

Aber das kriegen wir mit der Zeit schon hin denke ich, sodass die Performance stimmt. später kann man dann über instancing nachdenken, ist ja jetzt nicht so dringend. Erstmal wollt ich noch coole Effekte wie motion blur oder 2d lightning in das Spiel bringen ;)
Aber wie gesagt: erstmal aufräumen -.-


Aber ich kann demnächst mal wieder hier Screenshots posten oder so..

Was gäbe es denn noch interessantes im Thema Partikelsystem zu tun? Irgendwas was man einbauen kann bzw wie man das System verbessern kann..

mfg
 
AW: Partikelsystem für eigenes Spiel

Ihr braucht kein ASM für ein Partikelsystem. Wäre zwar nett aber übertrieben - viele Spieleentwickler zeigen ja das es ohne geht.
Ihr könnt es schon mit Vertexes machen, dann sollte aber euer Stichwort "Instancing" sein ;)

Ansonsten aufpassen, dass ihr keinen zu großen CPU<->GPU austausch habt - heißt also pro Renderdurchgang Daten an den GPU Senden sondern am besten schon compiled auf der Graka.
 
AW: Partikelsystem für eigenes Spiel

Noch mal eben eine andere Frage, wo ich mir nicht sicher bin, ob es Sinn macht.
Ich hatte unterschiedliche "Typen" von Emittern geplant. Da wären:
- Die Normalen, deren Emission man mit StartEmit() und StopEmit() steuert und die auch nur zerstört werden, wenn man es explizit sagt.
- Die Einmaligen, die eine bestimmte Zahl von Partikel haben, die sie ausstoßen und sich dann selber zerstören. Auf Wunsch bzw nach den Einstellungen werden alle Partikel sofort im nächsten Frame abgeschossen. Hierbei habe ich an Gegner gedacht, die bei Zerstörung verschwinden und an deren Stelle dann ein paar hundert Partikel Blut auftauchen, welches dann herumspritzt. (Hört sich brutal an, aber ist es natürlich nich so :D). Das Problem hierbei ist nämlich, dass keine Klasse den Emitter zerstören kann. Die Gegnerklasse wurde selber nach dem Tot schon zerstört, also fände ich es gut, wenn es so selbst zerstörbare gibt.
- Die auf Zeit gehen. Man gibt eine Zeit an, nach der der Emitter zerstört wird.

Haltet ihr diese Unterteilung für sinnvoll und viel wichtiger: Wie würdet ihr das machen? Ich dachte irgendwie an ein enum, welches den Typ angibt. Aber so wirklich reingedacht habe ich mich da noch nicht.


Zweite Frage: Ich möchte gerne ein Softkill für Partikel haben. Also, dass die Partikel nicht direkt verschwinden, sondern schon vorm Tot langsam transparent werden. Das alle hängt eigentlich zusammen mit Shadern, die auf die Partikel angewendet werden. Ich kenne mich leider wenig mit Shadern aus, aber es wird doch möglich sein, die Transparenz als Funktion in Abhängigkeit der Lebensdauert zu machen oder? Und von der Performance sollte das auch gehen, auf jeden Partikel einen Shader anzuwenden oder?

Wäre über Antworten dankbar :P

mfg
Lukas
 
AW: Partikelsystem für eigenes Spiel

Zur 2. Frage:
Ich weiss ja nicht wie das in DX abläuft aber so verschieden wird es da nicht sein - denke ich.
In OpenGL gibt es z.B. glColor4f(R, G, B, A)
Wobei RGB die Farbwerte angibt und A den Alphawert - also die Transparenz.
A = 1.0 nicht transparent
A = 0.0 komplett unsichtbar

Jetzt müsstest du nur was simples schreiben, was pro Sekunde vllt. 0.25 den Alphawert verringert und so wäre der Partikel nach 4 Sekunden weg und das schön langsam. Aber wie gesagt, kenne mich nicht in DX aus aber sowas wie RGBA muss es dort geben...
 
AW: Partikelsystem für eigenes Spiel

Ja mir ging es auch eher darum, ob man sinnvoll da die Lifetime reinkriegt. Weil Shader sind ja in der Graka und die Lifetime im normalen Ram und weil ich keine Ahnung habe, ist das für mich noch so die Frage. Kann man externe Daten bequem in den Shader kriegen? Und ist das ineffizent, wie du (AMD) schon gesagt hast, weil ein großer austausch zwischen Graka und dem Rest des Systems ist?
Ich würde in dem Zusammenhang direkt auch noch mein weiteres Vorhaben erklären: Spezielle Shader für Feuer zb. dass die Farbe von Gelb über Rot in grau übergeht. Sowas wäre fein :D
Aber für beides muss ich gerade mal Funktionen mir ausdenken.

Jedenfalls ist hier erstmal die Frage, ob das leicht zu realisieren ist.
 
AW: Partikelsystem für eigenes Spiel

Also bei OpenGL bekommt man die sehr bequem in den Shader ^^ Da wird DX dem nichts nachstehen nur ich habe davon echt keine Ahnung! :ugly:
Es kommt halt immer auf die Menge der Daten an und wie oft das passiert. Du musst ja z.B. nicht für jedes Frame Daten zur Grafikkarte schicken ;)
Nur als Beispiel (auch wenn das nichts mit Shader zutun hat): Ich lass bei mir meine Steuerung nur 60 mal pro Sekunde aktualisieren, auch wenn ich mit 1000 Frames rendere! Sieht letztendlich trotzdem total weich. Zum einen liegts am 60 Hz Monitor zum anderen an den langsamen Augen :D

Also du verstehst schon was ich meine!
Letztendlich die Kommunikation zwischen GPU so gering wie möglich halten (da muss man gerne mal etwas rumspielen bis man ein gutes Ergebnis hat) und das mit den Werten zum Shader sollte nicht so Wild sein (solange es nicht jedesmal tausende Werte sind). Wie muss du selber gucken^^
 
AW: Partikelsystem für eigenes Spiel

Also ich hab jez mal die ganzen Klassen aufgeräumt, und will gerade mal meinen aktuellen Stand hier reinschreiben :D

In einem Testprogramm, sieht eine Flamme so aus:
http://sebi707.de/downloads/files/0000654/ParticleTest.png

Das ist mit den Einstellungen:
Code:
EmitSource                  = Vec2f(0.f,0.f);
        EmitSourceDimension         = Vec2f(128,128);
        SourceSpeed                 = Vec2f(0.f,0.f);
        EmitRatePerSecond           = 300.0;
        Friction                    = 1;
        LifeTimeVariation           = 0.25;
        MaxParticle                 = 700;
        MovementInheritance         = 2.0f;
        LifeTime                    = 1.f;
        EmitDirection               = Vec2f(0,-0.1);
        DirectionDifference         = 3.1415926f;
        ForceOnParticles            = Vec2f(0, -0.1f);
Ich hoffe, es erklärt sich alle von alleine. Alle diese Attribute haben ihre gewünschte Wirkung auf das Partikelsystem. Mein Kumpel hat das System jetzt auch netterweise in die Engine integriert. Also sind jetzt auch mehrere Emitter möglich.
Mal gucken wie ich jetzt weitermachen werde.

mfg
Lukas

PS: Wer die Demo haben möchte, kann sich per PN melden..
 
AW: Partikelsystem für eigenes Spiel

Also für die Transparenz und für die Farbänderungen brauchst du erst mal keine Shader. Wofür hat man denn eine Vertexfarbe ? ;)
Du musst das ganze nur von der Lifetime abhängig machen. Für die Transparenz könnte man das z.B. so berechnen:

Code:
float Alpha = (*iParticle)->CurrentAlphaValue; // CurrentAlphaValue ist ein float, Member der Particle-Class
float subalpha = (*iParticle)->LifeTime / ElapsedTime; // ElapsedTime ist die Zeit, die für das letzte Frame gebraucht wurde
if (subalpha != 0.f) // hier ist ein float != Vergleich, das kann man noch verbessern 
{
	subalpha = Alpha / subalpha; 
	(*iParticle)->Alpha -= subalpha;
}
if ((*iParticle)->CurrentAlphaValue < 0.f) 
        (*iParticle)->CurrentAlphaValue = 0.f;

So sieht es etwa bei mir aus.

Was die verschiedenen Emitter angeht:
Bei mir ist das ganze 1 Klasse. Man kann per ParticleSystem->Fill(Emitter,Num) einmalig spawnen und per ParticleSystem->AddEmitter(Emitter) den Emitter zur Liste im System hinzufügen, sodass er automatisch jedes Frame spawnt. Das mit dem selbst zerstören ist immer so ne Sache... Man kann im Destruktor zwar prinzipiell "delete this;" aufrufen, aber du kannst nie wissen, ob das Objekt evtl. auf dem Stack liegt. -> Crash.

Lg
 
AW: Partikelsystem für eigenes Spiel

UPDATE:
Falls diesen Thread mal wieder jemanden interessiert, ein kleines Update :P

Ich habe jetzt angefangen das Partikelsystem für 3D fit zu machen. Das war schwerer als gedacht und ich habs nur Dank Hilfe eines Kumpels geschafft (so Rotationsmatrizen waren mir vollkommen fremd). Jedenfalls funktioniert es jetzt perfekt in 2D und 3D. Leider ist die Engine, mit der ich arbeite, bzw deren Grundlage ja mein Kumpel programmiert, noch nicht so weit für 3D, zb. gibt es noch keine Billboards. Daher verzichte ich auch vorerst mal auf Bilder, weil es einfach nur doof aussieht zurzeit.
Bilder oder vllt ein Video werde ich nachreichen, sobald ich was tolles geschaffen habe.
Außerdem habe ich gerade den tollen Renderstate D3DRS_DESTBLEND geändert, dass es echt cool aussieht.
Wie gesagt, Bilder folgen nachher wenn ich was schönes gebastelt habe.

Meine nächsten Vorhaben werden sein: Einen coolen Shader zu schreiben für Feuer Partikel. Aber damit warte ich noch auf das Materialsystem was in die Engine noch eingearbeitet wird..

so weit erstmal
schönen Abend noch
Lukas
 
AW: Partikelsystem für eigenes Spiel

Sorry für den DoublePost, aber sonst merkt ja keiner, dass sich hier was tut.
Hier hab jetzt einen simplen Test gemacht wie es zurzeit aussieht:

Particle Test 1 - Programming by sebi707 and Crysis nerd - YouTube

Dummerweise ist das Video doof geworden weil 1. wegen der zweifachen Framerate Umwandlung es teilweise doch aussieht, als ob es ruckelt und 2. weil ich mit der Kamera um den 3D Emitter rumfahre aber es nur so aussieht, als ob die Kamera die ganze Zeit verruckeln würde. Sorry deswegen, aber ich garantiere und verspreche euch: Es läuft mit flüssigen 60 FPS ohne Frameeinbrüche.

mfg
Lukas
 
Zurück