Project Frontier #18: Particle Man

By Shamus
on Jul 25, 2011
Filed under:
Programming

frontier17_5.jpg

I’m actually taking a break from the project this week to work on some other things, but there are a few completed features I want to cover. Let’s start with the particle engine.

I wrote a particle engine about eight years ago, as part of my day job. It was good for its time, but since then I’ve come up with a lot of ways that it could have been done better.

I’m using the term “particles” here very broadly to refer to any small objects that are created in groups and have no physical presence. They don’t collide with stuff, they can’t be picked up or manipulated. They are visual only. Some examples of particle effects from other games include: Fire, smoke, fireworks, billowing fog, puffs of dust when you take a step, splashes of water droplets, things blowing in the wind, rain, snow, blowing sand, muzzle-flashes, airborne blood spatters, magic missiles and other spell effects.

I don’t need all of those effects, but any system I build needs to be at least flexible enough to produce them.

Particles come from particle emitters, and particle emitters are created using a long list of settings. The settings are things like:

  • Texture – What texture to apply to all of the particles that this emitter will create. If I need more than one texture (say, if I wanted to make a shower of gold coins and rubies) then I’ll need to use multiple emitters. I could alter this so that an emitter could use multiple textures from a list, or maybe cut up and use selected sections of a texture. But for now this is good enough.
  • Blending style – Note how fire or muzzle flashes seem to emit light of their own, while smoke and dirt to not. This is controlled by how I set the blend properties at render time. “Bright” particles (and other special effect) are usually created so that they lighten the pixels already on-screen, which is what makes them glow.
  • Emitter lifespan – How long should this emitter last? A burst of fireworks releases all of its particles at once, after which the emitter is useless and can be discarded, while a plume of smoke is expected to keep churning out smoke as long as it’s in the scene.
  • Emission count & emission interval – How often should particles be released, and how many should appear when they do? Sparks from a loose wire might release a bunch of particles at once, but wait for several seconds between busts. A fire creates flames at a steady rate, and creates them one at a time.
  • Fade in & out – We need a way to control how long it takes for particles to appear and vanish. Fog and smoke should fade in and out very slowly. A burst of fireworks appears instantly, but fades out slowly. The aura of a blinking light should come and go instantly.
  • Rotation – Something blowing in the wind should tumble through the air, while raindrops should remain pointed the same direction.
  • Size – Some particles effects will be larger than others.
  • Cubic volume – The volume of the emitter is a cubic area. New particles will appear at a random point inside of the volume. If you want all of the particles to come from a single point, you make this volume zero size. If you want to make the churning spray at the base of a waterfall, you’d make the volume roughly the size of the area where the falling water is striking the still water.
  • Color – What color to tint the particles. I make all of the particle textures white and use this property to color them as needed. With any luck, I’ll be able to re-use textures and effects.
  • Other – I’ve got a few other properties for special cases: Should particles be pulled down by gravity? Should they be affected by wind? Should they leave an imprint of the z buffer?

First steps:  Here I’ve got an emitter (the blue wireframe box) creating particles. (The blue rectangles.) These particles appear, persist for a second, then vanish.
First steps: Here I’ve got an emitter (the blue wireframe box) creating particles. (The blue rectangles.) These particles appear, persist for a second, then vanish.

The upshot is that one set of properties will create one kind of particle effect, but a different set of numbers will yield an entirely different effect. Rather than have them hard-coded, I stick these settings into text files where I can edit them while the program is running. Here is an example, the effect I use for flower petals blowing in the wind:

<cvars>
    <particle_texture>  particle_flower.png    </particle_texture>
    <particle_acceleration>  [ 0,  0,  0.0 ]    </particle_acceleration>
    <particle_blend>  0 </particle_blend>
    <particle_emitter_lifespan>  0   </particle_emitter_lifespan>
    <particle_emit_count>  1    </particle_emit_count>
    <particle_emit_interval>  400    </particle_emit_interval>
    <particle_fade_in>  5    </particle_fade_in>
    <particle_fade_out>  500    </particle_fade_out>
    <particle_interpolate>  0    </particle_interpolate>
    <particle_lifespan>  3000    </particle_lifespan>
    <particle_origin>  [ 0,  0,  -0.25 ]    </particle_origin>
    <particle_panel_type>  3    </particle_panel_type>
    <particle_rotation>  [ 0,  0,  0 ]    </particle_rotation>
    <particle_size_min>  [ 0.07,  0.07, 0.07 ]    </particle_size_min>
    <particle_size_max>  [ 0.17,  0.17, 0.17 ]    </particle_size_max>
    <particle_speed_min>  [ 2,  -1,  0.05 ]    </particle_speed_min>
    <particle_speed_max>  [ 3,   1,  0.25 ]    </particle_speed_max>
    <particle_spin>  [ 20,  40,  0 ]    </particle_spin>
    <particle_volume_min>  [ -2,  -2,  1.0 ]    </particle_volume_min>
    <particle_volume_max>  [  2,   2,  1.1 ]    </particle_volume_max>
    <particle_wind>  0    </particle_wind>
    <particle_gravity>  0    
    <particle_z_buffer>  0    </particle_z_buffer>
</particle_gravity></cvars>

Now I can feed an emitter a list of colors.  When it creates a particle, it selects randomly from the available colors.  It’s now using a texture map (of a circle) and making them slowly spin through the air.
Now I can feed an emitter a list of colors. When it creates a particle, it selects randomly from the available colors. It’s now using a texture map (of a circle) and making them slowly spin through the air.

Thanks again to glConsole, which is the gift that keeps on giving. I was able to use its environment variable system to load these particle properties, basically for free.

The next step is to populate the world with emitters. I make a system to examine the local climate and time of day and pick an appropriate emitter. Swamp? Swirling ground fog. Desert? Blowing sand. Field of flowers? Blowing flower petals. Evening in an open area? Fireflies.

I set the particles to all move and spin at the same speed, which produces this ever-spooling ribbon effect. Cute.
I set the particles to all move and spin at the same speed, which produces this ever-spooling ribbon effect. Cute.

Other parts of the program can initiate one-off effects. When the avatar takes a step, it looks at the color of the terrain under its foot and creates a puff of particles. This looks great on sand or dirt, but kind of lame on grass. But you get the idea. It’s just one more thing making the world seem more like a living thing and less like a static scene.

Next time I’ll talk about those clouds you’re seeing in the screenshots.


Link (YouTube)

Because.

Enjoyed this post? Please share!


202020161 comments? This post wasn't even all that interesting.

From the Archives:

  1. samy says:

    An idea for grass could be to have swarms of grasshoppers and insects running away from your character to land a few feet away :)

  2. Kdansky says:

    I do imagine that you could put an emitter on every single tree, and make it throw leaves into the wind whenever a gust comes, like on a perfect autumn evening. That would look sweet.

    Where is the Video Of Pretty showing this off? Let my eyes feast! I demand it, or else I will do horrible, unspeakable, unspecified things to something or someone in my reach! I will take a potted plant as a hostage and slowly murder it by forgetting to water it! If it dies an agonising death, it’s your fault.

    Completely unrelated: How long can a cactus survive without water? Surely, it can’t be that long?

    • HeroOfHyla says:

      Well here in AZ we only get around 11 inches of rain per year, and most of that is in the summer. Cactus are quite good at surviving without water.

    • lazlo says:

      My mom got a jade plant when I was in high school and put it in the windowsill. I’m 39 now, and I’m pretty sure it hasn’t been watered yet. You might be waiting a while.

      On a note related to the topic at hand, I think I’m sensing a trend with this project. First there were the awesome flower groundcover, now there are flower petals blowing in the wind. It’s going to be flower-world, and the enemy will be Allergy-man!

      Although I’m pretty sure that he’s doing this to avert the possibility that some big name game co will come out with a triple-A title featuring a procedurally generated immense world filled with procedurally generated brown chest-height walls, which he would be forced to simultaneously love and hate.

  3. TSHolden says:

    Why is particle_z_buffer inside of particle_gravity?

    Shamus, have you considered writing a procedural version of Flower? The ribbon effect really reminds me of that game (one of my favorite ps3 titles). Seems like blowing debris around a procedural world would be fun.

  4. Eric says:

    Impressive, and also very simple and easy to understand. I’ve always sort of wondered how particle effects are built in games, and I imagine your approach is probably a lot more straightforward than some others out there.

    One question, are we going to get a final video update at some point to show these new improvements? I mean, come on, you’ve been teasing us how long now?

  5. Hitch says:

    What? You think you’re Mumbles now with the music video? ;-)

  6. Deoxy says:

    Heh – Particle Man. That’s a fun song. I remember when it was new.

    Yep, feeling old – happens more and more often these day.

  7. Aldowyn says:

    I just realized… what’s up with the avatar in the later pictures? That doesn’t look like it could be caused by the particles :/

  8. Alan says:

    Does anyone know what is that curious ‘instrument’ played by the guy in the red shirt?

    For some reason it reminds me of a theremin, based on the type of sound I guess…

  9. nawyria says:

    On a completely different sidenote, the “categories” widget seems to have vanished for me from your sidebar. Is this intentional, I kind of miss him?

    P.S.: I do not have an Adblocker on that I know of.

  10. Benjamin says:

    I thought it was customary for particle textures to be orthogonal to the viewer’s line of sight, and have any flipping done via animation. Perhaps you don’t feel the time would be well spent? I could see that.

    • neolith says:

      That depends on what effect you want to achieve. Some look better facing the cam (dust for example), some look better not doing so (leaves blowing in the wind).

  11. Octal says:

    Oooo, neat!

    Also, those big rocks sticking up out of the ground look pretty cool. As do the crossed trees.

    (Hopefully this isn’t a double post; the page didn’t load when I first tried.)

  12. Coderro says:

    I take a more animation style approach to defining particles. I give them a number of frames, and specify most of their data per frame. This means that, for example, fade in and out are achieved by the alpha being different on different frames and the frames being interpolated between. For good control, don’t code the frames as being spaced evenly but rather allow the time one occurs at to be specified.

  13. Alex the Elder says:

    Thank you SO bloody much for the earworm first thing in the morning. ;_;

    Also, I’m still seeing the tag down on the last line next to the tag so that it encloses particle_z_buffer, and I JUST loaded the post so it’s not a cache of the old text…

    And finally, the week of Halo 2 SWs has got me eagerly awaiting your adding a physics engine to your project. >:-)

  14. Gantidae says:

    Particle Man. Memory rush like I haven’t experienced in a long time.

  15. Tyler says:

    Shamus! I will be personally offended if this project is finished without weather patterns being implemented! I will track you down and beat you with an organic carrot. (Not really)

    But still. Weather, Shamus.

    As soon as you mentioned rain, it got me thinking. Snowy areas of the map will of course drop slow, wavering snowflake sprites. Tropical areas will drop rain the most. You know, the basic brainstorm.

    But with weather, you must also have ambient thunder, wind noises. And with those wind noises comes that sound you hear of trees rustling (trees emit it when there is a GLOBALEVENT_GUST?).

    Sorry for being so sloppy. I just dumped my brain on the keyboard as it came out.

  16. Zak McKracken says:

    Hey Shamus, you might find this interesting, it’s from this year’s SIGGRAPH:
    http://graphics.stanford.edu/~jtalton/research/Talton10MPM.paper/Talton10MPM.pdf

    Apparently there are other people working on procedural stuff, too :)
    I just skimmed over it, and you probably won’t like the mathematics part, but it should be good for some inspiration, and the literature list is quite long, too.

    Also, I hope you do read posts this old …
    Cheers

  17. […] the height of the terrain), with various objects (such as grass, trees etc) added. What he’s done so far is quite beautiful, and I’m hoping some kind of playable game will come out of it.  But […]

  18. Steve Healy says:

    I know it’s been a while but I can’t seem to find any news anywhere so I thought I’d ask here: is this project still going to be worked on or is it indefinitely on hold or something?

    I’ve loved it so far and would hate to see it end, these tech series you write are always extremely informative, and even without the code I’m learning a great deal from this series and would really love to see you keep working on it.

  19. Josh Kidd says:

    I take it this isn’t a thing anymore? What a cliff-hanger ending, I wanted to know about the clouds :/

  20. Heche says:

    Are you ever going to finish this? I was really enjoying reading it.

  21. hammackj says:

    Any updates/word on releasing the source? Looks like it has been a while since a update.

    Thanks!

  22. Jack V says:

    I was rereading the Project Frontier series and it’s really beautiful! Did you ever post a video with the wind and clouds? Or decide to release the source code?

    Edit: Doh! Sorry, source code at http://www.shamusyoung.com/twentysidedtale/?p=15808, for some reason I couldn’t find it before I posted! :)

  23. WJS says:

    As this is the last page of this project, I thought I’d just take the opportunity to curse you, Shamus, for making me want to write something like this myself. Given my experience with C++ (about a month some time in the late 90s? I dunno) and graphics programming (a big fat 0, beyond reading this), this is somewhat problematic. Trying to learn while doing something this ambitious seems like a really bad idea, yet I don’t think I’ll be able to resist trying.

3 Trackbacks

  1. By Procedural Worlds | Hot-Pink Monkey Socks on Mon Aug 8, 2011 at 11:51 pm

    […] the height of the terrain), with various objects (such as grass, trees etc) added. What he’s done so far is quite beautiful, and I’m hoping some kind of playable game will come out of it.  But […]

  2. […] Project Frontier ( video ) […]

  3. By Remplaçons les commerciaux | singularite on Thu Feb 9, 2012 at 3:45 am

    […] Project Frontier ( video ) […]

Leave a Reply

Comments are moderated and may not be posted immediately. Required fields are marked *

*
*

Thanks for joining the discussion. Be nice, don't post angry, and enjoy yourself. This is supposed to be fun.

You can enclose spoilers in <strike> tags like so:
<strike>Darth Vader is Luke's father!</strike>

You can make things italics like this:
Can you imagine having Darth Vader as your <i>father</i>?

You can make things bold like this:
I'm <b>very</b> glad Darth Vader isn't my father.

You can make links like this:
I'm reading about <a href="http://en.wikipedia.org/wiki/Darth_Vader">Darth Vader</a> on Wikipedia!

You can quote someone like this:
Darth Vader said <blockquote>Luke, I am your father.</blockquote>