Domanda

Sto progettando il mio proprio motore sistema di particelle, questo è a fini di apprendimento, non ho voglia di utilizzare un motore esistente.

In questo momento ho generato belle particelle, ma voglio il layout del motore per rendere più facile lavorare con loro.

Ho riflettuto su una classe "Sistema di particelle",

che la classe dovrebbe contenere i seguenti riferimenti:

particlesList :. Un elenco delle particelle che compongono il sistema

systemEmitter : L'emettitore sistema di particelle, la classe emettitore dovrebbe essere in grado di eseguire diverse tecniche di emissione di particelle, come per esempio, emettendo dalle linee, punti, emettendo caso da un poligono. Anche questa classe dovrebbe fare emissione Controlling, come emettendo verso un punto, lontano da un punto, in una direzione e il tempo per emettere.

particleController : gestisce ad esempio la rotazione intorno ad un punto, granulometria variabile, colori particelle variabili, zone intorno al sistema di cui le particelle reagiscono in modi diversi, rilevamento di collisione (con altri oggetti o all'interno particelle se diventa necesary).

Particelle renderer : preposto alla redazione questo sistema, i tipi di fusione variabili, texture di particelle, tipi di particelle, come triangoli, cerchi, su misura ...

Questa quattro voci, avrebbero comporre la classe sistema di particelle. Alcuni FX può richiedere più di un sistema di particelle, ad esempio un incendio FX, potrebbe utilizzare un sistema per il fuoco, un sistema per il fumo e un sistema per scintille.

Questo è quello che ho in mente, ma mi piacerebbe molto sapere se questo approccio progettuale è buono, o se vedete mi manca qualcosa o potrebbe / dovrebbe fare qualcosa di diverso. Non ho pensato a un modo semplice per "salvare" FX, come ad esempio quello che sarebbe il modo migliore per dire il mio motore, "attirare il fuoco", "disegnare esplosione", "disegnare fontana", ecc, forse la memorizzazione delle informazioni FX in XML file sarebbe una buona idea, etc ..

Le opinioni sono davvero benvenuti, e come ho detto prima, ho davvero voglia di costruire questo, invece di utilizzare un altro motore, per motivi di apprendimento.

È stato utile?

Soluzione

Questo set-up dovrebbe andare bene. Quello che mi auguro che stai pensando a è ciò che i dati costituiranno una particella che sarà nella classe di particelle. Avrai voglia di avere solo lo stretto necessario in modo da avere solo per leggere / scrivere il meno memoria possibile durante l'esecuzione del sistema.

Per quanto riguarda rendendo basati su dati che dovrebbero essere piuttosto semplice. Vorrei suggerire un'opzione formato binario per il carico e xml. in modo da poter modificare facilmente cose durante lo sviluppo (e non avere uno strumento). Una volta che si dispone di uno strumento o sono fatto tweaking vorrei convertire il XML a binario per il caricamento rapido.

Si può anche prendere una classe di manager che gestisce la creazione e l'aggiornamento di questi sistemi di particelle. Questo sarebbe anche consentire a un atto per gestire altre funzionalità che ha a che fare con tutti i sistemi. Alcuni esempi di questo sono un fattore limitante la quantità di sistemi di particelle o particelle che possono essere gestiti per motivi di prestazioni o avente un piano di collisione che tutti i sistemi tengano conto.

Lei parla di questo è per fini di istruzione e in ciò che riguarda queste cose sono schizzinosi piuttosto nit (ma importante se si è di utilizzare questo in un gioco che è pesante particella).

Io parto dal presupposto questo sta usando un'API come DirectX o OpenGL per il rendering. A questo proposito vorrei avere gli effetti particellari tutti condividono lo stesso pool di memoria per le informazioni vertice. Questo aiuta la velocità di rendering molto. Vorrei anche tenere traccia di una limiti della zona colpita da un sistema di particelle per l'uso con tronco di abbattimento (AABB o Circle).

Una parte enorme di aggiornamento di un sistema di particelle è come attributi vanno da un valore all'altro. La dinamica più si può fare l'interpolazione dei valori meglio gli effetti possono guardare. Semplicemente interpolando linearmente potrebbe essere abbastanza buono, ma può essere meglio avere un grafico dinamico che viene utilizzato per interpolare i valori. Ad esempio, invece di passare da 0 a 255 blu in un secondo, può essere fresco per andare 0 e 128 in 0.2 secondi e poi 128-255 in 0,8 secondi. Aggiungendo che aumenterà notevolmente le opzioni su come gli effetti aspetto.

Oltre a questo penso che tu abbia una buona idea di ciò che si vuole fare. Il tuo menzione di rendere diversi tipi di particelle mi dice che sta pensando a questo nel modo giusto. Ho visto persone che fanno i motori di particelle appena concentrandosi su rendere un quad billboarded. Avere la possibilità di emettere la geometria 3D rende davvero le cose sembrano grandi. Si potrebbe anche voler pensare (se non lo avete già fatto) avere la capacità per il vostro sistema a prendere informazioni sul modello e dividere dinamicamente la in particelle separate per essere emessa. Effettivamente esplode un modello sembra molto meglio quindi visualizzare alcuni particella esplosione e dissolvenza fuori l'oggetto o il passaggio ad uno stato danneggiato.

Altri suggerimenti

Solo alcune idee per l'ottimizzazione di semplici particelle di sprite 2D.

Una buona idea è quella di inviare tutte le particelle in una matrice vertice / VBO, e utilizzare un vertex di aggiornare le loro posizioni nel tempo. Questo è grande se si ha un movimento semplice che può essere facilmente descritto utilizzando una formula matematica dove x(t) e y(t) (cioè, dipendono solo dal tempo).

Un'altra grande idea sta usando sprite punto, invece di triangoli e quadrati. Questo dovrebbe ridurre la larghezza di banda richiesta sul gasdotto a un quarto.


Nel mio spazio sim ho implementato l'approccio più banale: le particelle inviati come quad strutturato utilizzando glBegin() / glEnd(). Essi vengono scaricati in "settore" corrente come singoli oggetti e sono completamente indipendenti dai tempi di scarico in poi. Questa è la cosa più primitivo, stupido, e idiota da fare ed è responsabile per la forte riduzione delle prestazioni, soprattutto perché quello che faccio è scorrere oggetti tramite iteratore STL del vettore e mando tutti e ciascuno di loro in modo sequenziale.

È necessario considerare il numero di particelle che si desidera, e che cosa vuoi che facciano. * Vuoi loro di reagire a un ambiente e si scontrano? Quindi è necessario l'aggiornamento gestito sulla CPU e dati inviati più e più volte. * Hanno appena volano intorno nel modo più stupido possibile? Poi si può essere in grado di farla franca con l'invio di tutte le particelle come VBO e TBO, e aggiornarle in shader.

Buon divertimento!


Aggiornamento di relazionarsi con il commento # 1 dal richiedente: -)

Quello che vorrei fare è utilizzare le href="http://en.wikipedia.org/wiki/KISS_principle" BACIO principio . Ciò significa: una classe denominata ParticleEmitter contenente una matrice di vertice, un array di velocità, e un vector STL con esempi di semplici acceleratori quali piano, sfera, triangolo. Inoltre, avere un vector * STL "globale" con collider. Quindi aggiornare le velocità secondo collisori.

simile può essere fatto con affectors (gravità, vento e simili): un altro vettore STL in ParticleEmitter con affectors e un altro STL vector "globale" con affectors.

Affectors e collisionatori sarebbe classi che implementare affectParticle(particle_t*). dove struct particle_t { float x,y,z; float vx,vy,vz; }. Vorrei tenerlo una struttura POD, ed eseguire l'aggiornamento a ParticleEmitter::update().

Tuttavia, se si esegue questo su iPhone, potrebbe essere overcomplication? Forse si può ottenere via con quello che già implementato? Non ho idea di come il mio progetto potrebbe influenzare i risultati dei benchmark, ma suona abbastanza ragionevole per me se si mantiene la particella, collider e affector conto alla rovescia, perché suona come potrebbe scalare con circa il n*c+n*a.

Questi sono solo i miei pensieri ad hoc, e come io personalmente attuarlo. Il vostro disegno, o il disegno di altre persone, probabilmente sarebbe meglio: -)

* "Global" sotto le virgolette, perché sarebbe probabilmente un senso di fare uso di qualsiasi spazio di partizionamento che avete in uso.

Ho implementato lo stesso buon design per il mio motore in C ++. Non ho usato i riferimenti e le politiche di template (strategie - leggere "moderna C ++ Disegno" di Alexandresku), invece. polimorfismo statico dà prestazioni migliori.

Voglio fare alcuni commenti secondo la mia esperienza.

  1. Tradizionalmente, la maggior parte delle particelle utilizza AOS (Array of Struct) per memorizzare gli attributi di particelle. Ma questo non può essere la decisione migliore. L'utilizzo di SOA (struct di Array) rappresentazione vi darà un sacco di flessibilità per l'aggiunta di attributi di ogni sistema di particelle. E, inoltre, vi sarà molto più facile per migliorare le prestazioni con SIMD con la SOA. Ad esempio, facendo 4 particelle insieme con istruzioni SSE.
  2. posizione in cui la particella emette solo inizializzazione di un attributo particella. Quando si emettono particelle, probabilmente è necessario inizializzare altri attributi, come la vita, velocità, ecc Si può abstract tutte queste funzionalità come inizializzatori. Per la posizione, si può avere un inizializzatore disco, contenitore di inizializzazione, ecc.
  3. Alcuni sistema di particelle moderna adotta il concetto di evento. sistema di particelle può generare evento (ad esempio pioggia collidono con terreno) e l'altro sistema particellare può ascoltare ed eseguire una certa azione (per esempio emettono spruzzo).

A proposito, penso che il modo migliore è quello di studiare il progetto di applicazione / middleware esistenti, e anche dalla sperimentazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top