Tilføye turbulens til et partikkelsystem

Du kan skape en rekke effekter med partikkelsystemer. I denne artikkelen skal jeg beskrive en enkel måte å forbedre dem ved å legge til litt turbulens. Jeg starter med et 2D-partikkelsystem for enkelhet. Kodeeksempler er i Javascript, men de er for det meste matte, så det er enkelt å tilpasse dem til noe annet språk.

Relaterte innlegg
  • Lag ditt spillpop med partikkeleffekter og quadtrees
  • Opprette jevn partikkelutslipp med underrammeinterpolering
  • Lag en koselig, snøaktig nattscene ved hjelp av partikkeleffekter
  • Objektpuljer hjelper deg å redusere lag i ressursintensive spill


Regelmessig partikkelsystem

La oss starte med å lage et vanlig partikkelsystem i 2D. Vi bruker enkle sprites med:

  • Stilling: x, y.
  • Hastighet: vx, vy.
  • Scale.
  • Alfa (gjennomsiktighet).
  • Livstid, så vi vet når du skal gyte partikkelen.

Oppdaterer partikler

For hver partikkel oppdaterer vi hastigheten først. I dette tilfellet har vi bare fuktet det litt for å gjøre bevegelsen mer interessant og realistisk. Krafter som tyngdekraft eller vind kan også brukes her.

 var dempning = 1-0.005 this.vx * = demping this.vy * = demping

Deretter oppdaterer vi posisjonen ved hjelp av hastigheten. Vi bruker fast tidstrinn for denne opplæringen. Hvis tiden din varierer, må du multiplisere hastigheten ved din tid delta for å få endring i posisjon.

 this.x + = this.vx this.y + = this.vy

Vi skalere partikler litt for å simulere ekspanderende røykputer.

 this.scaleAll (1,01)

Vi gjenbruk partikler i stedet for å fjerne og legge til dem siden vi vil ha konstant flyt her:

 this.life- = 1 if (this.life<=0) this.respawn(particleLifetime)

Og til slutt oppdaterer vi partikkel gjennomsiktighet for å fade dem ut over tid.

 this.alpha = this.life / particleLifetime

De respawn Metoden setter bare innledende verdier for partikkelen. Det brukes også til å fylle partikkelsystemet ved oppstart.

 this.x = jaws.width * (Math.random () * 0.1-0.15) this.y = jaws.height * (0.45 + Math.random () * 0.1) this.vx = Math.random () * 2+ 4 this.vy = (Math.random () + Math.random () + Math.random () - 1.5) * 2 this.life = livet this.scaleTo (1)

Legge til Vortices

Den definerende egenskapen for turbulens er vorticiteten. Så den enkle og enkle måten å simulere turbulens er å skape et virvelobjekt som påvirker partikkelbevegelsen.

La oss begynne med å beregne hastigheten i virvelkanten, som om det ville være et solid hjul.

Hastighet ved punktet på hjulet. Hjulbilde av Pearson Scott Foresman fra Wikimedia Commons.

Først trenger vi en vektor fra vortex senter til partikkelen:

 var dx = particle.x-vortex.x var dy = particle.y-vortex.y

Da roterer vi vektoren 90 grader for å lage en ortogonal en og multiplisere den med rotasjonshastigheten for vortex:

 var vx = -dy * vortex.speed var vy = dx * vortex.speed

Flott, vi har den hastigheten som virvelprøven prøver å tvinge på partiklene, men hvordan bruker vi den?
Vi trenger litt vektningsfaktor som vil være 1 i sentrum av hvirvelen og vil tynne ut med avstand.
Vi bruker denne ad hoc-formelen, som er basert på invers kvadrat-avstand, men unngår singularitet i sentrum:

 var faktor = 1 / (1+ (dx * dx + dy * dy) / vortex.scale)

Vektfaktorkurve.

La oss bruke vortexhastigheten ved å blande den med partikkelen ett:

 particle.vx + = (vx-particle.vx) * faktor particle.vy + = (vy-particle.vy) * faktor

Det er det, vi har en virvel som påvirker partikler nå!


Flytte virvler

En enkelt statisk vortex er bra for å finne ut hvordan man bruker den til partiklene, men vi vil ha flere vorter, og vi vil at de skal bevege seg rundt. La oss bare gjøre dem til et annet (usynlig) partikkelsystem! Så nå har de også hastighet og levetid. Det vil trenge noen endringer i koden.

Når vi beregner hastigheten i virvelkroppen, må vi også legge til hvirvelbevegelsen:

 var vx = -dy * vortex.speed + vortex.vx var vy = dx * vortex.speed + vortex.vy

Og vi vil at virvlene skal falme inn og ut jevnt, ikke bare pop plutselig inn og ut av eksistensen. La oss bruke en enkel kurve til vektningsfaktoren:

 var lifeFactor = vortex.life / vortexLifetime factor * = (1-lifeFactor) * lifeFactor * 4

Scaling vortex med sin levetid.

Hva kan gjøres med Vortex Motion

I eksemplet for denne opplæringen bruker jeg flere virvler som beveger seg likt partiklene, men har litt kortere levetid. Imidlertid kan bevegelige vorter på forskjellige måter, i tillegg til å justere rotasjonshastigheten og rekkevidden, produsere en mengde forskjellige effekter.

For eksempel, siden en virvel forsøker å bevege partikler med den, vil en statisk hvirvel forsøke å stoppe partikler som flyr gjennom den og sette dem i en virvel. Du kan bruke denne effekten til å skape et turbulent område som senker partikler som kommer inn i det.

Du kan lage hvirvler når et tegn beveger seg i spillet, eller når et objekt knuser i bakken.

Kármán vortex gate forårsaket av vinden som strømmer rundt Juan Fernández-øyene utenfor den chilenske kysten. Bilde av Bob Cahalan fra Wikimedia Commons.

En vanlig turbulenseffekt er vortexgata som også er lett å gjenskape, for en statisk gjenstand i strømmen eller for et raskt bevegelige objekt.

Du kan også kollidere vorter med miljøet eller la tegnbevegelsen påvirke dem.


forbedringer

Jeg roterte ikke partiklene i eksemplet. Det er lett å legge til og det forbedrer det vanlige partikkelsystemet, men det kan forbedres ytterligere ved å bruke vorter. Bare bland partikkels rotasjonshastighet med virvel som vi gjorde med den lineære hastigheten.

Du kan forbedre vortexbevegelsen ved å la andre vorter påvirke den, akkurat som med partikler.

Ulike vortexvektingsfunksjoner kan gi forskjellige resultater. Jeg brukte bare en ad hoc som fungerte for dette eksempelet, men du kan finne andre mer passende for saken din. Ganske mye noe som fader ut med avstanden fra sentrum vil gjøre.


Går 3D

Teknikken er også enkel å bruke i 3D. Bruk 3D vektorer for posisjoner og hastigheter (inkludert vortex vinkelhastighet), og beregne hastigheten i virvelkroppen ved bruk av kryssprodukt:

 Vector3 r = particle.position-vortex.position; Vector3 v = Vector3.Cross (vortex.angularVelocity, r);

Hastigheten i virvelkroppen beregnes med kryssprodukt.

Andre måter å gjøre turbulens på

Selvfølgelig er det ikke den eneste måten å gjøre turbulens og ikke den eneste måten å gjøre vortexer på. La oss se på noen andre.

Embedded Vortices

Vi brukte listen over vorter på nivået av partikkelsystemet. Det er ganske effektivt, men du kan lagre en virvel (eller flere) i hver partikkel.

Mens det trenger mer minne, forbedrer det datalokaliteten og gjør det mulig å tilpasse partikkelbevegelsen enda mer. Du kan randomisere vortexen litt for hver partikkel eller bruke flere lag vorter for å få 2D-partikkelsystemet til å se mer 3D.

Global Vortices

I stedet for å lagre listen over vorter i partikkelsystemet, kan den gjøres global. Dette sparer minne og CPU-tid som oppdaterer vorter. Det er også enkelt å legge til nye vorter som skyldes tegnbevegelse, kolliderer vorter med miljø osv.

Væskesimulering

Du kan gå en mer realistisk rute og gjøre faktisk fysisk simulering av strømmen. Det er sannsynligvis for tungt for alt moderat størrelse i 3D uten GPU-databehandling, men ganske mulig i 2D. Det finnes gridbaserte metoder (du vil ha flere oppløsninger for ytelse) og partikkelbaserte. Se også på å legge tilbake tapte vorticity ved hjelp av støy, det er papirer på det.

Vorticity Grid

I stedet for å gjøre en full fysisk simulering eller partikkellignende vorter, kan du lagre vorticiteten i et rutenett. Lagre vinkel- og lineære hastigheter og formidle dem på hvert trinn. Deretter, i partikkelsystemet, prøv rutenettet for å finne vortexhastigheten som påvirker partikkelen.

Det er ikke like realistisk som væskesimulering, men det er mye raskere, siden du ikke trenger å løse fullgittertrykksligninger, bare formere og dempe hastigheter.

Prosedyre Støy

Hvis du bare vil ha mye kaotisk turbulens uten uttalt vortex ("boblende"), kan det være en bedre ide å bruke prosessjonsstøy. Se etter Perlin eller simplex støy. Du trenger en ekstra dimensjon, slik at du kan animere støyen. Så for 2D trenger du 3D-støy rullet i den tredje dimensjonen med tiden, og 4D-støy for 3D.

Du kan prøve støy flere ganger på noen faste forskyvninger for å få komponenter av kraften som påvirker partikkelen.


Konklusjon

Nå kan du forbedre partikkeleffekter ved å legge til et sekundært system av vortexpartikler. Tenk deg en eksplosjon forårsaket av et rakett som tvinger nærliggende røyk til å virke rundt blastradiusen, eller etterlater hvirvler når de flyter nedover en elv. Eksperimenter med hvordan du gyter og flytter hvirvler for å oppnå ønsket effekt eller oppdage noe nytt!