3
\$\begingroup\$

How is prewarming in particle engines made?

I have a particle engine and need to support this, which is a feature I have already seen in Unity.

Is it done at compilation, like informations stored somewhere? or pre-processed at launch? or is there a way to simulate a particle system when it is created?

Considering it is time based, I don't see how I could for example simulate 15 seconds of life for a particle system without actually using 15 seconds

\$\endgroup\$
  • 1
    \$\begingroup\$ You wouldn't have to use 15 seconds because you could quickly iterate through the simulation, stepping it at intervals that approximate real timesteps, without actually needing to wait for those timesteps. \$\endgroup\$ – MichaelHouse Jun 27 '14 at 18:38
  • \$\begingroup\$ Yes I just found a way to do it that works, I'll update my post soon with the solution used. Thanks! \$\endgroup\$ – Malharhak Jun 27 '14 at 18:43
  • 4
    \$\begingroup\$ @Malharhak Don't update your post -- please your post your own answer below! \$\endgroup\$ – Vaughan Hilts Jun 27 '14 at 19:27
  • \$\begingroup\$ My bad, that's what I meant actually \$\endgroup\$ – Malharhak Jun 28 '14 at 8:27
2
\$\begingroup\$

I ended up with a simple idea that worked surprisingly good, so here it is:

In my particle engine, I generate n particles per gameloop tick, and running at 60 FPS we have, for an elapsed time t in seconds, n * 60 * t particles generated.

This could vary if your game isn't fluid and frames drop, but we assume it runs correctly.

Now what happens is that the prewarn function is launched once the particle emitter starts, and emits this number of particles. Then we have to simulate where they are, because they should have been all generated at different dates, when in truth they haven't.

All of this is done with a simple for loop (example in JavaScript):

particles.prewarm = function () {
    // FPS = 60, this.rate = number of particles per gameloop tick, this.life = life of a particle in seconds
    var particlesCount = (FPS * this.rate) * this.life; // Gets the number of particles to emit
    var timeUnit = this.life / particlesCount; // This is the amount of time between two particles for the duration of our simulation

    for (var i = 0; i < particlesCount; i++) {
        var p = this.emit(); // Emit a random particle

        // Here, we set the "birth" date of each particle at their simulated point in time
        p.birth = time.time - this.life + timeUnit * i;
        p.update (time.time - p.birth); // Here I call my particle's update with a special deltaTime which corresponds to the duration of the simulation for this particle
    }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ BTW, just as a simplification, timeUnit is equal to 1.0 / (FPS * this.rate), since the factors of this.life cancel out. \$\endgroup\$ – Nathan Reed Jun 28 '14 at 8:45
  • \$\begingroup\$ True, there's lot of room for optimization in this code anyway \$\endgroup\$ – Malharhak Jun 28 '14 at 8:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.