2013-10-15 60 views
0

我在JavaScript中有一个基本的粒子系统(利用画布进行渲染),我试图找到处理粒子之间碰撞的最佳方法。该粒子系统可以处理大约70,000个粒子,并且具有相当不错的FPS。在JavaScript/canvas粒子系统中处理碰撞

它由一个包含每个粒子对象的数组组成。每个粒子对象包含3个矢量对象(一个用于位移,速度和加速度),它们包含一个x和一个y变量。 在每帧之前,加速度矢量应用于速度矢量,速度矢量应用于每个单个粒子对象的位移矢量。 渲染器然后遍历每个粒子,然后在每个位移矢量的位置绘制一个1x1像素的正方形。

粒子系统还具有“磁性”场,这可能会导致粒子加速朝向/远离给定点。

我试着给每个粒子应用一个'磁场',但是我用来获得每个粒子的更新加速度矢量的计算效率太低,这种方法大大降低了FPS。

下面是我用它来重新计算粒子加速度矢量,相对于附近的磁场(此功能每帧之前调用)的代码:

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); 
} 

这是显而易见的,为什么上面的方法大大降低了性能 - 每增加一个新粒子,计算次数就会成指数增长。

是否有另一种粒子碰撞检测方法,能够在数千个粒子中获得良好的性能?这些方法是否适用于我目前的对象结构?

+1

粒子系统本身是非常耗资源的,如果你另外做70k +粒子的碰撞检测,恐怕JavaScript对你无能为力。即使有宏观优化(在这种情况下可能很重要),您将看到性能上的困难。通常情况下,这些东西都是使用低级代码(汇编器或c/C++)与硬件加速的3D卡相结合的。事件有时必须呈现(这在Pro视频世界中是正常的)。你可以评估你是否愿意在我认为是最好的机会的粒子数量方面做出妥协。 – K3N

+0

如果可能的话,我会建议你给我们提供一个小提琴,我们可以与之一起玩,并与我们一起做一些优化。可以看到从那里得到的结果(即使它会根据硬件配置而变化) – K3N

回答

1

不要在这里创建一个新的向量。这意味着你每帧创建70 000个新的向量。只需更改矢量值:

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

如果没有足够的帮助,您将不得不使用WebWorker。