Cannon.js предоставляет мощный физический движок для симуляции твёрдого тела в браузере на JavaScript. Один из ключевых аспектов оптимизации производительности — правильная конфигурация World и итераций решателя. Неправильные настройки могут привести к снижению FPS и нестабильности симуляции, особенно при большом количестве объектов.
Объект CANNON.World является центральным элементом
симуляции. Он управляет всеми телами, коллайдерами и взаимодействиями.
Основные свойства, влияющие на производительность:
gravity – вектор гравитации
(CANNON.Vec3).broadphase – стратегия широкого поиска
столкновений. Доступны NaiveBroadphase и
SAPBroadphase. SAP (Sweep and Prune) более эффективен для
большого числа тел.solver – объект решателя
(CANNON.GSSolver), который вычисляет реакции сил между
телами.solver.iterations – количество
итераций решателя за один шаг симуляции. Увеличение значения повышает
точность, но снижает производительность.solver.tolerance – допустимая
погрешность при решении ограничений. Меньшие значения повышают точность
контактов, но увеличивают нагрузку на CPU.Пример базовой настройки World:
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
world.broadphase = new CANNON.SAPBroadphase(world);
world.solver.iterations = 10;
world.solver.tolerance = 0.001;
Каждый шаг физической симуляции включает решение системы ограничений (constraints) для всех взаимодействующих тел. Решатель (Solver) выполняет итерации, чтобы приблизить решения к реальному физическому поведению.
Высокое количество итераций
Низкое количество итераций
Баланс между точностью и производительностью достигается экспериментально. Для большинства браузерных игр достаточно 5–10 итераций.
Пример ограничения итераций:
world.solver.iterations = 5; // минимальная нагрузка, базовая точность
world.solver.tolerance = 0.01; // допустимая погрешность для ускорения симуляции
Broadphase отвечает за предварительное определение пар
тел, которые могут сталкиваться. Это снижает количество проверок
столкновений.
NaiveBroadphase Проверяет все пары объектов, что даёт сложность O(n²). Подходит для малого количества тел.
SAPBroadphase Оптимизирован для длинных сцен с множеством объектов. Работает по принципу сортировки тел вдоль оси и проверки только потенциально пересекающихся.
Комбинация SAPBroadphase и уменьшенного количества итераций решателя обеспечивает заметное повышение FPS без критической потери точности.
world.broadphase = new CANNON.SAPBroadphase(world);
world.solver.iterations = 7;
Cannon.js позволяет контролировать частоту обновления физики через fixedTimeStep:
const timeStep = 1 / 60; // 60 шагов в секунду
function updatePhysics(deltaTime) {
world.step(timeStep, deltaTime, 3); // последняя цифра – maxSubSteps
}
maxSubSteps – максимальное
количество подшагов за один кадр.
Оптимальное сочетание: умеренное количество итераций решателя + SAPBroadphase + ограничение maxSubSteps.
В сложных сценах может понадобиться адаптивное изменение количества итераций в зависимости от нагрузки:
function adjustSolverFPS(currentFPS) {
if (currentFPS < 30) {
world.solver.iterations = 3; // минимальная нагрузка
} else if (currentFPS < 50) {
world.solver.iterations = 5; // средняя точность
} else {
world.solver.iterations = 10; // максимальная точность
}
}
Такой подход позволяет поддерживать стабильный FPS и одновременно сохранять адекватную точность физической симуляции.
Правильное управление итерациями решателя и настройка World является критическим элементом производительности Cannon.js, особенно при работе с большим числом объектов. Оптимизация этих параметров обеспечивает баланс между реализмом физики и плавностью визуализации.