0

I have a basic particle system in JavaScript (utilising canvas for rendering), and I'm trying to find the best way to handle collisions between particles. The particle system can handle about 70,000 particles at a pretty decent FPS.

It consists of an array that contains every Particle object. Each Particle object contains 3 Vector objects (one for displacement, velocity, and acceleration) which contain an x and a y variable. Before each frame, acceleration vectors are applied to velocity vectors, and velocity vectors are applied to displacement vectors for every single Particle object. The renderer then iterates through each Particle and then draws a 1x1 pixel square at the location of every displacement vector.

The particle system also has 'magnetic' fields also, which can cause the particles to accelerate towards/away from a given point.

I tried applying a 'magnetic' field to each particle, but the calculations I use to get the updated acceleration vectors for each particle are too inefficient, and this method reduced the FPS considerably.

Below is the code I use to recalculate Particle acceleration vectors, with respect to nearby magnetic fields (This function is called before every frame):

Particle.prototype.submitToFields = function (fields) {
    // our starting acceleration this frame
    var totalAccelerationX = 0;
    var totalAccelerationY = 0;

    // for each passed field
    for (var i = 0; i < fields.length; i++) {
        var field = fields[i];

        // find the distance between the particle and the field
        var vectorX = field.point.x - this.point.x;
        var vectorY = field.point.y - this.point.y;

        // calculate the force via MAGIC and HIGH SCHOOL SCIENCE!
        var force = field.mass / Math.pow(vectorX*vectorX+vectorY*vectorY,1.5);

        // add to the total acceleration the force adjusted by distance
        totalAccelerationX += vectorX * force;
        totalAccelerationY += vectorY * force;
    }

    // update our particle's acceleration
    this.acceleration = new Vector(totalAccelerationX, totalAccelerationY);
}

It's obvious why the above method reduced the performance drastically - the number of calculations rises exponentially with every new particle added.

Is there another method of particle collision detection that will have good performance with thousands of particles? Will these methods work with my current object structure?

Sosumi
  • 759
  • 6
  • 20
  • 1
    Particle systems in themselves are very resource hungry and if you in addition do collision detection of 70k+ particles I'm afraid JavaScript won't help you much. Even with macro-optimizations (which can be important in a case like this) you will see performance struggle. Typically these things are made using low-level code (assembler or c/c++) combined with hardware accelerated 3D cards - event then sometimes things must be rendered (which is normal in the pro video world). You could evaluate if you're willing to do a compromise in the number of particles which I think is the best chance.. –  Oct 15 '13 at 07:08
  • If possible I would suggest you provide us with a fiddle we can play around with and do some optimizations with and we can see what the result will be from there (even though it will variate depending on hardware configuration) –  Oct 15 '13 at 07:12

1 Answers1

1

Don't create a new Vector here. It means that you're creating 70 000 new Vectors each frame. Just change the vector values :

this.acceleration.x = totalAccelerationX; // or : this.acceleration[0] = totalAccelerationX;
this.acceleration.y = totalAccelerationY; // or : this.acceleration[1] = totalAccelerationY;

If it doesn't helps enough, you'll have to use a WebWorker.

Sebastien C.
  • 4,649
  • 1
  • 21
  • 32