2013-10-15 3 views
0

У меня есть базовая система частиц в JavaScript (с использованием холста для рендеринга), и я пытаюсь найти лучший способ обработки столкновений между частицами. Система частиц может обрабатывать около 70 000 частиц при довольно приличном FPS.Обработка столкновений в системе частиц JavaScript/canvas

Он состоит из массива, содержащего каждый объект Particle. Каждый объект Particle содержит 3 объекта Vector (один для перемещения, скорости и ускорения), которые содержат переменную 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

Системы частиц сами по себе очень ресурсоемкие, и если вы дополнительно обнаруживаете столкновения частиц 70 к +, я боюсь, что JavaScript вам не поможет. Даже при макрооптимизации (что может быть важно в таком случае) вы увидите борьбу с производительностью. Как правило, эти вещи выполняются с использованием низкоуровневого кода (ассемблера или c/C++) в сочетании с аппаратными ускоренными 3D-картами - события, тогда иногда вещи должны быть визуализированы (что нормально в мире видеороликов). Вы могли бы оценить, хотите ли вы пойти на компромисс в количестве частиц, которые, по моему мнению, являются наилучшим шансом. – 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.

Смежные вопросы