1 / 54

Particles by example

Particles by example. Bas Zalmstra Maarten Wiedenhof Tigran Gasparian. Who are these guys?. Abbey Games Bas Zalmstra Programmer Maarten Wiedenhof Artist. Who are these guys?. Contents. Talk Why Particles? Tools The basics Adding effects Emitter Shapes Blending

zarita
Download Presentation

Particles by example

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Particles by example Bas Zalmstra Maarten Wiedenhof TigranGasparian

  2. Who are these guys? Abbey Games • Bas Zalmstra • Programmer • Maarten Wiedenhof • Artist

  3. Who are these guys?

  4. Contents • Talk • Why Particles? • Tools • The basics • Adding effects • Emitter Shapes • Blending • Particle Hierarchy • Optimization • Fluids • Lunch • Workshop

  5. Why Particles?

  6. Rami Ismail – “You can never have enough particles”

  7. Tools

  8. Tools • Programming each individual effects sucks • Introducing: Particler • Used to create all particles in Reus and in this presentation

  9. Tools • One of the many tools created for Reus • Artists (and game designers) can’t code (stupid ass) • WYSIWYG • Allows for quick iteration • Shows particle count and update time • Written in C# • Winforms, XNA • Saves particle effects to XML • Thin wrapper around the engine

  10. The Basics The basics

  11. The basics • Particle • Position, velocity • Time to live • Particle • Emitter • Creates new particles over time • Defines initial values • Emitter

  12. Emitter • Spawns new particles • Everything based on Parameters • Number of particles to spawn • Random velocity • Random color • Random lifetime • Texture

  13. Code void Update(floatdeltaTime) { // Remove dead particles foreach(Particle p inactiveParticles) { p.TimeToLive -= deltaTime; if(p.TimeToLive <= 0) Remove(p); } // Spawn new particles    Emit(deltaTime); // Move each particle; ds=dt*vforeach(Particle p inactiveParticles) p.Position += p.Velocity * deltaTime;}

  14. The basics • Demo time

  15. The Basics Adding effects

  16. Effects • Currently looks static & repeating • Lets apply some effects • Change size over time • Change color over time • Add some form of gravity

  17. Effects • Demo time

  18. Size • Linear interpolate size over lifetime of particle • Vector2.Lerp(Vector2 a, Vector2 b, float x) voidApplyScale(Vector2 beginSize, Vector2 endSize, Particle p) { p.Size = Vector2.Lerp( beginSize, endSize, p.TimeToLife / p.TotalLifeTime);}

  19. Fade • Linear interpolate color over lifetime of particle voidApplyFading(Color beginColor, Color endColor, Particle p) { p.Color = Color.Lerp( beginColor, endColor, p.TimeToLife / p.TotalLifeTime);}

  20. Fade • Can also use 1D Gradient • Sample random color • Sample over time

  21. Add Force • Newton’s 2nd law: F=ma • a=F • Simply set mass to 1 voidApplyForce(Vector2force, floatdeltaTime, Particlep) { p.Velocity+= force*deltaTime; }

  22. Combine void Update(floatdeltaTime) { // Remove dead particles foreach(Particle p in activeParticles) { p.TimeToLive -= deltaTime; if(p.TimeToLive <= 0) Remove(p); } // Spawn new particles    Emit(deltaTime); // Modify Particles foreach(Particlep inactiveParticles) { ApplyScale(beginSize, endSize, p); ApplyFading(beginColor, endColor, p); ApplyForce(force, deltaTime, p); } // Move each particle; ds=dt*vforeach(Particle p in activeParticles) p.Position += p.Velocity * deltaTime;}

  23. Problem • Adding other effects introduces: • Parameters • (Possible unnecessary) processing • Larger emitter class • Needs cleanup

  24. Solution • Extract to class: Modifier • ForceModifier • ScaleModifier • ColorModifier • Pro’s: • Separation of code! (Code metrics++) • Plugins • Pay only for what you need (processing wise) • Con: • Extra virtual member call (slower, however, negligible)

  25. Extract to class void Update(floatdeltaTime) { // Remove dead particles foreach(Particle p in activeParticles) { p.TimeToLive -= deltaTime; if(p.TimeToLive <= 0) Remove(p); } // Spawn new particles    Emit(deltaTime); // Modify Particles foreach(Modifier mod inmodifiers) mod.Update(deltaTime, activeParticles); // Move each particle; ds=dt*vforeach(Particle p in activeParticles) p.Position += p.Velocity * deltaTime;}

  26. Blending

  27. Look at these examples • Some wallpapers

  28. Opacity, Transparency, Alpha component • Confusing terminology • 100% transparent = 0% opaque = 0% alpha = “invisible” • 0% transparent = 100% opaque = 100% alpha = “fully visible” • Alpha blending • result = Lerp(destination, source, source.alpha) • Additive blending • result = destination + source • Many particle systems use additive blending! • Fire, energy, electricity, light, etc.

  29. Particle Hierarchy

  30. Particle Hierarchy • Particles emitting particles! • You can have properties inherited onto the child particles • As always, avoid cycles 

  31. Optimization

  32. Optimization • Working with 1000+ particles can get slow • Especially if manipulated every frame • Avoid copying all particles • Using unsafe context • Use multithreading

  33. Removing dead particles - Naive • Error: Collection was modified; enumeration operation may not execute. voidRemoveDeadParticles() { // Remove dead particles foreach(Particle p inactiveParticles) { if(p.TimeToLive <= 0) activeParticles.Remove(p); }}

  34. Removing dead particles – double buffer • Memory allocation is slow voidRemoveDeadParticles() { // Create new listList<Particle> currentlyActiveParticles = newList<Particle>(); // Copy over particles that are still aliveforeach(Particle p inactiveParticles)     { if(p.TimeToLive> 0) currentlyActiveParticles.Add(p);     } // Set new list as activeactiveParticles = currentlyActiveParticles;}

  35. Removing dead particles – smart copy • Probably more life particles than dead ones • Remove instead of add voidRemoveDeadParticles() { // Copy over particles that are still alive intnextAliveParticle = 0;for(inti = 0; i < activeParticles.Length; ++i)    { if(p.TimeToLive> 0) activeParticles[nextAliveParticle++] = activeParticles[i];    } }

  36. Removing dead particles – remove dead voidRemoveDeadParticles() { intlastIndex = activeParticles.Length – 1; intcurrentIndex = 0; while(currentIndex <= lastIndex)    { if(activeParticles[currentIndex].TimeToLife <= 0) activeParticles[currentIndex] = activeParticles[lastIndex--]; else currentIndex++;     } // Remove end of the list (fast) if(lastIndex < activeParticles.Length-1) activeParticles.RemoveRange(lastIndex+1, activeParticles.Length – lastIndex - 1); } • Copy life particle from the end of the list to the location of the dead particle • Also changes render order 

  37. Unsafe context in C# • For those familiar with C++ • Work directly with memory • Turned off by default • Many times faster than List<Particles> • Easy to make crucial mistakes • Also hard to find

  38. Multithreading • Particle systems can easily be multithreaded • As long as particles don’t interact with each other • Spread computation over multiple cores • Can easily be done with Parallel.ForEach or Parallel.For • Watch out for overhead • Not very usefull for small number of particles.

  39. Multithreading voidMoveParticles(floatdeltaTime) { // Move each particle; ds=dt*vforeach(Particle p inactiveParticles) p.Position += p.Velocity * deltaTime;} voidMoveParticlesMultithreaded(floatdeltaTime) { // Move each particle; ds=dt*v Parallel.ForEach(activeParticles, p => { p.Position += p.Velocity * deltaTime; });}

  40. Fluids

  41. There are other ways • We showed you today • Individual particles, with properties, moving about • For smoke, atmospheric systems and fluids, a different approach can be used

  42. A grid of points • Each point holds values • Points never move • Evenly distributed • Every point influences its neighbors • Compare • Lagrangian: track individual particles flowing through space • Eulerian: keep track of static points, with values flowing through them

  43. Buy Reus

  44. Workshop ideas • Additional emitter properties • Texture animation • Funky color • Rotation

More Related