Search code examples
javascriptthree.jsparticle-system

Three.js / ShaderParticleEngine — SPE.Group.tick bad delta argument?


I'm using the ShaderParticleEngine library for Three.js to create particle emitters.

I picked several code snippets on the Internet to have a working emitter. Firstly I believed that is wasn't working.

But in fact, the emitter was displayed on the map, but a single motionless particle was on the screen. After some debugging I undestood that the particle was moving but infinitely slowly. I need to use tick(delta * 1000) to see the emitter in action. And the result is quite ugly (full of gaps, alone particles).I have no problem of low FPS.

The only solution I found is to remove delta argument in the tick function call: particleGroup.tick().

The result is better but is still deceiving, judge by yourself:

Online Emitter Editor: Editor

My result: Ingame

I can't understand. I use the same code proposed in the library examples and I use the export feature in the emitter editor. If I try other variations (eg. on particle life/velocity) I get a very different result in my game, maybe the particle life is not computed correctly because delta argument isn't given?

My game loop:

var animate = function () {

    requestAnimationFrame( animate );

    render();

    stats.update();

};

var render = function() {

    time = ctx3d.clock.getElapsedTime();
    delta = ctx3d.clock.getDelta();

    particleGroup.tick(delta);

    if(ctx3d.move)
    {
        ctx3d.ship.position.z += delta * 500 * 3000;
        //ctx3d.camera.position.x = ctx3d.ship.position.x;
        //ctx3d.camera.position.z = ctx3d.ship.position.z;
    }

    ctx3d.renderer.render(ctx3d.scene, ctx3d.camera);

}

Delta value loop by loop:

30.0000010000003385357559 9.999985195463523e-7 30.0000020000006770715117 0.0000010000003385357559 30.0000020000006770715117 0.0000010000003385357559 0.0000020000006770715117 30.0000010000003385357559 0.000002999999196617864 0.0000010000003385357559 9.999985195463523e-7 0.000002999999196617864 0.0000010000003385357559 0.000001999998858082108 0.0000010000003385357559 20.0000020000006770715117 9.999985195463523e-7 0.0000010000003385357559


Solution

  • I hope posting this as an answer is okay...

    I've bumped the particle engine up a minor version to 0.7.7, having implemented a fix for your issue of "not-very-smooth-looking" emitters.

    What was happening before was this:

    • SPE.Emitter.tick() called with a dt value
    • This tick function determines how many particles should be marked alive based on the dt argument passed to it. For larger dt values, more particles are marked as alive, for smaller values fewer are marked as alice.
    • The emitter then resets these particles and waits for the next call.

    Assuming more than one particle is going to be marked as alive per frame, and they all originate at the same position in space, then all the particles will be at the same place when they're activated. This is why you saw some "clumping" happening.

    What happens now is this:

    • SPE.Emitter.tick() called with a dt value, just as before.
    • The tick function now determines how many particles should be marked as alive, and whilst marking them so, sets each particles age to be a fraction of the dt value passed in.

    So (!), assuming 100 particles are emitted per frame, and a dt value of 0.016 is passed to the emitter's tick function, each of those 100 particles that will be marked as alive is assigned an age value of (0.016 / 100) * i where i is the particle index (in this case, a value of 0 to 100).

    I hope that makes sense. You can see the changes here: https://github.com/squarefeet/ShaderParticleEngine/blob/master/src/ShaderParticleEmitter.js#L240-L246

    Master branch has been updated.