• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Slow Motion Particles, There Has To Be A Better Way?

R

robproctor83

Guest
Greetings friends, I am trying to implement an efficient slow motion particle system. The best method I have found to get delta timing to work is to stop the automatic update of the particle systems and then using an alarm with delta timing I manually update the systems forward one step. To get fluid motion the update function is called quite a lot. Unfortunately this creates a lot of processing it seems as the profiler reports the particle system to be about 3 times as long to process than everything else.

Recently I took a stab at trying to roll my own particle system, sadly it didn't turn out too god. To produce a similar number of particles on the screen as the normal systems my custom object emitter only performed about a third as good. Changing it so that the all the particles in a single system are drawn all at once from a ds_list rather than individual objects didn't do much better, it performed about 1/2 as effecient.

Is there any other possibilities? My working solution is okay enough, I can get around 300 to 500 fps with a dozen or two active particles, but that's on a good computer. I was thinking maybe a shader, but I wouldn't know were to even begin, or even if it's possible. Any other thoughts on how I could go about optimizing?
 

samspade

Member
I don't understand what you mean by: "To get fluid motion the update function is called quite a lot." That doesn't make sense to me. The particle system update should be called roughly the exact same as it would be if you weren't using a delta type system - that's the whole point of it.
 
R

robproctor83

Guest
What I mean is, in order to get particles to move in sync with delta time I disable their movement at creation with part_system_automatic_update(sys,false) and then manually move the particles forward one step I run this function part_system_update(sys) every couple milliseconds. So, if I wanted to get a smooth animation for 60fps then that means I need to run the update function roughly 60 times a second per particle system. This way I get the particles to only move in sync with the game speed, otherwise you can't change a particle once it's been emitted.

Now, thinking about this more though, I think I may be going about this slightly the wrong way. When I create the system I immediately disable the automatic updates, but maybe I should only do that when the slow motion effect kicks in and I need the particles to instantly slow down. The reason I had this running on creation of the particle system is because the user may turn vsync on/off and that will greatly alter the speed of things. However, I just need to watch for that change and then go through, resync all the particle variables and then just let the current particles that were drawn at the previous frame rate finish their animation in the wrong time scale as it should only be for a brief moment... Yes yes... this is good! This is very good! Ideas, coming to me! Also, running the manual part update isn't that bad, basically when slow motion kicks in performance increases by like 50% because everything is suddenly running much less frequently, like the particle update call. So, having that in-efficient method may be okay for the short moments of slow motion effects. I can't wait to get home and implement this! Hopefully it works... it should!
 

samspade

Member
"So, if I wanted to get a smooth animation for 60fps then that means I need to run the update function roughly 60 times a second per particle system."

Yes, that's true but that is what it would be by default. In other words, if you don't use a delta time with the particle system it is going to update roughly 60 times per second per particle system. Again, the whole point of a dt system is to emulate what would happen if it was running at 60, so if you are doing it correctly it will be roughly the same.

Now with slowdown, the system will actually update less - in other words once you start slowing the system down your ps will update slower than it would under real frame rate meaning it will be more 'optimized' if you want to think of that way.

I've implemented several slowmo particle systems and never experienced any decrease in performance when slowing the system down.
 
R

robproctor83

Guest
"So, if I wanted to get a smooth animation for 60fps then that means I need to run the update function roughly 60 times a second per particle system."

Yes, that's true but that is what it would be by default. In other words, if you don't use a delta time with the particle system it is going to update roughly 60 times per second per particle system. Again, the whole point of a dt system is to emulate what would happen if it was running at 60, so if you are doing it correctly it will be roughly the same.

Now with slowdown, the system will actually update less - in other words once you start slowing the system down your ps will update slower than it would under real frame rate meaning it will be more 'optimized' if you want to think of that way.

I've implemented several slowmo particle systems and never experienced any decrease in performance when slowing the system down.
How did you go about making it? In the same way I am suggesting? I'd be interested in knowing the basics of what you did.

Also, are you saying whether I activate the particle system and let it run at it's native 60fps or do the manual update 60 times a second the FPS will be the same? I'll check that tonight and see... Its just that in the profiler the particles are like 15% of the total step, where as the next highest thing (enemies with motion paths and other complicated stuff), is only 5%. So, it concerns me that particles which are just eye candy is sucking up so much FPS. Doesn't seem right.
 

samspade

Member
It sounds like I did much the same thing disable the ps from the start and then in the step event have this code:

Code:
counter += 1 * dt;
if (counter >= 1) {   
   var counter_int = floor(counter);
   repeat (counter_int) {
       part_system_update(ps);
   }
   counter -= counter_int;   
}
And yes, there should be roughly no difference between a particle system running normally in a room set to 60 fps and running a ps update manually 60 times a second.
 
R

robproctor83

Guest
Interesting, thanks for sharing your code, that's a clever method of timing the update I wouldn't have thought of. I have a custom alarm system that uses delta timing, so I just set an alarm that runs ~60 times a second.

Well, check this out... I re-enabled the automatic update and just let the particles flow like normal and... wow... Huge DECREASE in performance! It dropped about 100 to 200 fps to let them run like normal. The thing that is really confusing me though is what the profiler is telling me. With normal flowing particles the profiler shows the particle object as very low in step processing, much much lower than before, it's under 2% now BUT I'm getting noticeably worse performance. When I have my custom timed particle update in place I get much better performance but the profiler tells me that my particle object is performing worse, around 15-20% total step which is much higher than everything else. So, I don't get it! Why does profiler tell me my particles are worse even though I experience a significant increase.... and vise versa....

Anyways, this is kind of a bummer, I had really hoped that would be the secret here. I'm not sure what all else I could really do. Even putting all into the same particle system and drawing them all at the same depth doesn't seem to work any better either... My only other course of action is to replace all static particle effects (like the fire on a wall torch) with rendered sprites, which is a lot better for performance, but it loses some of the aesthetic. Agh... Oh well I guess.
 

samspade

Member
Interesting, thanks for sharing your code, that's a clever method of timing the update I wouldn't have thought of. I have a custom alarm system that uses delta timing, so I just set an alarm that runs ~60 times a second.

Well, check this out... I re-enabled the automatic update and just let the particles flow like normal and... wow... Huge DECREASE in performance! It dropped about 100 to 200 fps to let them run like normal. The thing that is really confusing me though is what the profiler is telling me. With normal flowing particles the profiler shows the particle object as very low in step processing, much much lower than before, it's under 2% now BUT I'm getting noticeably worse performance. When I have my custom timed particle update in place I get much better performance but the profiler tells me that my particle object is performing worse, around 15-20% total step which is much higher than everything else. So, I don't get it! Why does profiler tell me my particles are worse even though I experience a significant increase.... and vise versa....

Anyways, this is kind of a bummer, I had really hoped that would be the secret here. I'm not sure what all else I could really do. Even putting all into the same particle system and drawing them all at the same depth doesn't seem to work any better either... My only other course of action is to replace all static particle effects (like the fire on a wall torch) with rendered sprites, which is a lot better for performance, but it loses some of the aesthetic. Agh... Oh well I guess.
It's possible that the profiler doesn't report the automated particle system update or does it somewhere else. But personally, I'd say don't worry about the FPS if you're still at 100-200. That's still a lot to work with. I wouldn't even attempt to optimize at that point. If you did want to optimize one thing you could do is set up some of the particle systems to run at half speed - essentially only update 30 times per second.
 
Top