Jump to content

Particle engine extension


Ravetracer
 Share

Recommended Posts

This discussion is meant to be the continuation of the thread in the Google Groups (https://groups.google.com/forum/#!topic/melonjs/DjW-aYKIVjk):

 

As of now, I've tested my implementation and it renders more and more inperformant when I add more emitters.
1 to 3 emitters are working in an example without any sound, map loading or something else. When I try to add 5 emitters, the performance drops tremendously!
Maybe there's a trick which I don't know currently and also I'm not so deep in developing Canvas engines.

If you want to see, what I've changed, here's the commit to my forked repository:
https://github.com/Ravetracer/melonJS/commit/32461498a9443991f4612a08a88367c243d3be9c

Regards,
Christian

Link to comment
Share on other sites

The last time I profiled the particle emitters, performance was very good; 2,500 particles on a 4-year-old MBP running at 50 fps (canvas) and 60 fps (WebGL). It was almost a year ago, though. Also, I haven't tried the emitter with particles that inherit from me.Sprite, so that might have something to do with it. The profiler built into your browser is probably going to be the best source of information about what's causing slowdown. It might be the case that the observable vectors are consuming far more time than they should, or such. That's why we have special-case classes for particles and emitters right now; they are optimized for speed, but have a less powerful API then the standard container and sprite classes.

Link to comment
Share on other sites

it's actually surprising, as your changes are somehow light... all you do is to calculate a new offset for the spritesheet, nothing more fancy than that.... but for sure, i mean if you sum-up this calculation for 10.000 particles (spread over 5 emitters) it can start making a difference.... maybe some caching would be useful ?

Now this said, what kind of usage do you have though for 5 emitters ? and how many particles do they generate totally ? my point is to know either or not this is still a realistic and acceptable use case (if you see what I mean)

Link to comment
Share on other sites

I've created 5 emitters to see, how far I could go ?. I don't know, if there's a useful real life situation for this.

Also I've uploaded my test project here: http://ravetracer.de/melontest

I've created a quick'n'dirty "setEmitter" function which adds an emitter with most values preconfigured:
 

function setEmitter(x, y, image, settings) {
    this.emitter = new me.ParticleEmitter(x, y);
    this.emitter.totalParticles = 180;
    this.emitter.minLife = 8000;
    this.emitter.maxLife = 12000;
    this.emitter.floating = false;
    this.emitter.z = 50;
    this.emitter.width = 2;
    this.emitter.gravity = 0;
    this.emitter.angle = 90 * (Math.PI / 180);
    this.emitter.angleVariation = 0.1;
    this.emitter.image = me.loader.getImage(image);
    this.emitter.numFrames = 13;
    this.emitter.frameWidth = 41;
    this.emitter.speed = 2.5;
    this.emitter.speedVariation = 1;
    this.emitter.wind = 0.07;

    me.game.world.addChild(this.emitter);
    me.game.world.addChild(this.emitter.container);

    this.emitter.streamParticles();
}

To test it, you simply can add new emitters by entering this in the developer console:

new setEmitter(350,450,'explosion_02_strip13');

 

Link to comment
Share on other sites

Quick profile shows that QuadTree (collision detection!) is responsible for the slowdown. (See attachment.)

Here's a patch for that:

me.QuadTree.prototype.insertContainer = function (container) {
    for (var i = container.children.length, child; i--, (child = container.children[i]);) {
        if (child instanceof me.Container && !(child instanceof me.ParticleContainer)) {
            if (child.name !== "rootContainer") {
                this.insert(child);
            }
            // recursivly insert all childs
            this.insertContainer(child);
        } else {
            // only insert object with a bounding box
            if (typeof (child.getBounds) === "function") {
                this.insert(child);
            }
        }
    }
};

With this (you can just paste it into the dev console) I am able to add 11 emitters before it starts to affect frame rate. And this is with the canvas renderer! With WebGL, I can get 16 emitters going at 60fps.

Beyond these limits, the update time on me.ParticleContainer and me.Particle together go over the 16.7ms frame budget.

Screen Shot 2016-12-07 at 12.37.42 PM.png

Link to comment
Share on other sites

:D

Glad we were able to help out! Olivier identified the issue was actually a regression introduced in version 3.0.0. The stress testing I ran was on 2.1.0!

I committed the workaround to the master branch, and we now have a feature request ticket to opt-out of collision detections on a per-object basis, instead of a hard-coded inheritance check.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...