Главная » Хабрахабр » [] Браузерная симуляция физики

[] Браузерная симуляция физики

В этой статье я хочу дать описание существующих решений для создания приложений с симуляцией физики, сравнить их производительность и предоставляемый инструментарий.

Введение

В статье будут рассмотрены следующие движки:

Ammo.js
Cannon.js
Oimo.js
box2dweb
Unity3D WebGL

Основной целью было выбрать наиболее производительный, удобный и легковесный движок для разработки игр и приложений с использованием симуляции физики.

Ammo.js

Является портом Bullet physics engine на javascript с использованием компилятора Emscripten и по заявлению разработчиков обладает практически идентичным функционалом. Функционал Ammo.js действительно обширен. Для работы с ним понадобится отдельная библиотека для визуализации. Чаще всего используется Three.js. При этом каждый цикл перерисовки придётся вручную синхронизировать положение и вращение каждого объекта на сцене с его физической моделью, движок не делает это автоматически.

Что касается производительности, она не слишком высокая, но и заметных просадок fps в большинстве проектов не будет.

API иногда может быть довольно запутанным и документация не особо помогает.
В целом очень хороший инструмент, который продолжает развиваться и дорабатываться.

Cannon.js

Cannon.js — легковесный физический движок с открытым исходным кодом. В отличие от предыдущего изначально писался на javascript и позволяет использовать все его возможности и оптимизации. На самом деле сложно сказать, является ли это плюсом или минусом, поскольку скомпилированный код может быть куда эффективнее написанного с нуля. Тем не менее cannon.js по сравнению с ammo.js считается более компактным, более производительным, а также более легким для понимания, но при этом он не обладает таким количеством функций. На практике их производительность часто примерно одинаковая.

Процесс работы с движком довольно прост:

// Инициализируем движок
var world = new CANNON.World();
world.gravity.set(0, 0, -9.82); // Устанавливаем гравитацию (движок использует единицы СИ) // Создаём объект и добавляем его на сцену
var radius = 1;
var sphereBody = new CANNON.Body({ mass: 5, position: new CANNON.Vec3(0, 0, 10), shape: new CANNON.Sphere(radius)
});
world.addBody(sphereBody); var fixedTimeStep = 1.0 / 60.0;
var maxSubSteps = 3; // Запускаем цикл симуляции
var lastTime;
(function simloop(time) lastTime = time;
})();

Для работы также требуется сторонняя графическая библиотека, причём придётся каждый цикл отрисовки вручную перемещать соответствующий объект на сцене на место расположения физического объекта.

mesh.position.x = body.position.x;
mesh.position.y = body.position.y;
mesh.position.z = body.position.z;
mesh.quaternion.x = body.quaternion.x;
mesh.quaternion.y = body.quaternion.y;
mesh.quaternion.z = body.quaternion.z;
mesh.quaternion.w = body.quaternion.w;

В данный момент движок практически не развивается, последняя активность в репозитории проекта более 2 лет назад, а на тот момент движок ещё только начинал развиваться, так что в некоторых местах он может оказаться не проработан.

Oimo.js

Oimo.js — переписанная на чистом javascript версия движка OimoPhysics. В сравнении с другими решениями, обладает очень хорошей производительностью и точностью, однако поддерживает только примитивную геометрию (кубы и сферы). Включён в состав Babylon.js — фреймворка для визуализации 2D и 3D графики, поэтому каких то дополнительных библиотек не потребуется.

// Инициализируем движок
world = new OIMO.World({ timestep: 1/60, iterations: 8, broadphase: 2, worldscale: 1, random: true, info: false, gravity: [0,-9.8,0] }); // Добавляем физические объекты
var body = world.add({ type:'sphere', size:[1,1,1], pos:[0,0,0], rot:[0,0,90], move:true, density: 1, friction: 0.2, restitution: 0.2, belongsTo: 1, collidesWith: 0xffffffff;
}); var body = world.add({ type:'jointHinge', body1: "b1", body2: "b1",
}); world.step(); // Копировать позицию и вращение так же нужно каждый цикл отрисовки
myMesh.position.copy( body.getPosition() );
myMesh.quaternion.copy( body.getQuaternion() );

Большим минусом движка является не очень качественная документация, но разработчики продолжают работу над ней.

На данный момент движок продолжает развиваться.

box2dweb

box2dweb — это порт box2d на javascript. Как понятно из названия, специализируется на симуляции 2D физики. Несмотря на это, box2dweb — довольно мощный инструмент, который нисколько не отстаёт от своих трёхмерных аналогов. Например движок включает крайне удобные системы обнаружения коллизий и имитации соединений (constraint).

Что касается производительности, нужно очень постараться писать не оптимальный код, чтобы появились просадки fps.

Из плюсов так же стоит упомянуть простоту API и удобную документацию.

Unity3D

Unity3D — популярный кросс-платформенный игровой движок. Включает в себя простой удобный drag&drop редактор и обширный инструментарий по созданию 3D-контента. Последняя версия движка для написания игровой логики поддерживает C#.

PhysX даёт обширный функционал по симуляции физики твёрдых тел, жидкостей и тканей, обладает очень хорошей производительностью, хотя многие плюсы аннулируются при работе на графических ускорителях не от NVIDIA. Unity имеет встроенную симуляцию физики, для этого используется встроенный движок PhysX от NVIDIA. Крайне приятным фактом является то, что с 3 декабря 2018 исходный код движка доступен под открытой лицензией BSD-3, тем не менее движок слишком сложный, чтобы пытаться переписывать его под себя или разбираться в его устройстве, так что тут лучше поможет документация.

Для этого достаточно в настройках сборки выбрать соответствующий пункт. В этом списке Unity оказался, поскольку существует возможность собрать проект на нём под WebGL.

Поэтому данный вариант не пользуется популярностью и я не стану его подробно рассматривать. Тем не менее WebGL версия Unity в силу особенностей своей архитектуры (трансляция кода из C# в С++ и далее в JavaScript), имеет ряд проблем с производительностью, потреблением памяти и работоспособностью на мобильных устройствах, и не похоже, что разработчики собираются с этим что-то делать в ближайшее время.

Сравнение производительности

Сравним производительность движков по тому, как они справляются с обработкой коллизий большого количества объектов. Используемый браузер — Firefox 64.0.2 x64.

Движок

fps при обработке 100 объектов

fps при обработке 500 объектов

fps при обработке 1000 объектов

ammo.js

40-50

25-27

15-25

cannon.js

30-40

20-25

15-20

oimo.js

45-55

35-40

35-40

По результатам тестов Oimo.js показывает лучшую производительность.

Кроме того заметно, что производительность всех сравниваемых движков довольно невелика, так что данные решения подойдут для написания далеко не каждой игры, но зато хорошо подойдут для создания небольших демо. Разумеется, эти результаты не дают адекватной оценки производительности, так как зависят от множества сторонних факторов, но полноценное исследование потребовало бы куда больше времени да и я такой цели себе не ставил.

Вывод

В целом, выбор конкретного движка зависит от поставленной задачи. Если требуется простой в понимании и легко осваиваемый движок — хорошо подходит Сannon.js или Oimo.js. Если требуется больше функционала, лучше использовать Ammo.js. В определённых ситуациях, если большая производительность не требуется, можно попробовать использовать Unity.

[] Браузерная симуляция физики

В этой статье я хочу дать описание существующих решений для создания приложений с симуляцией физики, сравнить их производительность и предоставляемый инструментарий.

Введение

В статье будут рассмотрены следующие движки:

Ammo.js
Cannon.js
Oimo.js
box2dweb
Unity3D WebGL

Основной целью было выбрать наиболее производительный, удобный и легковесный движок для разработки игр и приложений с использованием симуляции физики.

Ammo.js

Является портом Bullet physics engine на javascript с использованием компилятора Emscripten и по заявлению разработчиков обладает практически идентичным функционалом. Функционал Ammo.js действительно обширен. Для работы с ним понадобится отдельная библиотека для визуализации. Чаще всего используется Three.js. При этом каждый цикл перерисовки придётся вручную синхронизировать положение и вращение каждого объекта на сцене с его физической моделью, движок не делает это автоматически.

Что касается производительности, она не слишком высокая, но и заметных просадок fps в большинстве проектов не будет.

API иногда может быть довольно запутанным и документация не особо помогает.
В целом очень хороший инструмент, который продолжает развиваться и дорабатываться.

Cannon.js

Cannon.js — легковесный физический движок с открытым исходным кодом. В отличие от предыдущего изначально писался на javascript и позволяет использовать все его возможности и оптимизации. На самом деле сложно сказать, является ли это плюсом или минусом, поскольку скомпилированный код может быть куда эффективнее написанного с нуля. Тем не менее cannon.js по сравнению с ammo.js считается более компактным, более производительным, а также более легким для понимания, но при этом он не обладает таким количеством функций. На практике их производительность часто примерно одинаковая.

Процесс работы с движком довольно прост:

// Инициализируем движок
var world = new CANNON.World();
world.gravity.set(0, 0, -9.82); // Устанавливаем гравитацию (движок использует единицы СИ) // Создаём объект и добавляем его на сцену
var radius = 1;
var sphereBody = new CANNON.Body({ mass: 5, position: new CANNON.Vec3(0, 0, 10), shape: new CANNON.Sphere(radius)
});
world.addBody(sphereBody); var fixedTimeStep = 1.0 / 60.0;
var maxSubSteps = 3; // Запускаем цикл симуляции
var lastTime;
(function simloop(time) lastTime = time;
})();

Для работы также требуется сторонняя графическая библиотека, причём придётся каждый цикл отрисовки вручную перемещать соответствующий объект на сцене на место расположения физического объекта.

mesh.position.x = body.position.x;
mesh.position.y = body.position.y;
mesh.position.z = body.position.z;
mesh.quaternion.x = body.quaternion.x;
mesh.quaternion.y = body.quaternion.y;
mesh.quaternion.z = body.quaternion.z;
mesh.quaternion.w = body.quaternion.w;

В данный момент движок практически не развивается, последняя активность в репозитории проекта более 2 лет назад, а на тот момент движок ещё только начинал развиваться, так что в некоторых местах он может оказаться не проработан.

Oimo.js

Oimo.js — переписанная на чистом javascript версия движка OimoPhysics. В сравнении с другими решениями, обладает очень хорошей производительностью и точностью, однако поддерживает только примитивную геометрию (кубы и сферы). Включён в состав Babylon.js — фреймворка для визуализации 2D и 3D графики, поэтому каких то дополнительных библиотек не потребуется.

// Инициализируем движок
world = new OIMO.World({ timestep: 1/60, iterations: 8, broadphase: 2, worldscale: 1, random: true, info: false, gravity: [0,-9.8,0] }); // Добавляем физические объекты
var body = world.add({ type:'sphere', size:[1,1,1], pos:[0,0,0], rot:[0,0,90], move:true, density: 1, friction: 0.2, restitution: 0.2, belongsTo: 1, collidesWith: 0xffffffff;
}); var body = world.add({ type:'jointHinge', body1: "b1", body2: "b1",
}); world.step(); // Копировать позицию и вращение так же нужно каждый цикл отрисовки
myMesh.position.copy( body.getPosition() );
myMesh.quaternion.copy( body.getQuaternion() );

Большим минусом движка является не очень качественная документация, но разработчики продолжают работу над ней.

На данный момент движок продолжает развиваться.

box2dweb

box2dweb — это порт box2d на javascript. Как понятно из названия, специализируется на симуляции 2D физики. Несмотря на это, box2dweb — довольно мощный инструмент, который нисколько не отстаёт от своих трёхмерных аналогов. Например движок включает крайне удобные системы обнаружения коллизий и имитации соединений (constraint).

Что касается производительности, нужно очень постараться писать не оптимальный код, чтобы появились просадки fps.

Из плюсов так же стоит упомянуть простоту API и удобную документацию.

Unity3D

Unity3D — популярный кросс-платформенный игровой движок. Включает в себя простой удобный drag&drop редактор и обширный инструментарий по созданию 3D-контента. Последняя версия движка для написания игровой логики поддерживает C#.

PhysX даёт обширный функционал по симуляции физики твёрдых тел, жидкостей и тканей, обладает очень хорошей производительностью, хотя многие плюсы аннулируются при работе на графических ускорителях не от NVIDIA. Unity имеет встроенную симуляцию физики, для этого используется встроенный движок PhysX от NVIDIA. Крайне приятным фактом является то, что с 3 декабря 2018 исходный код движка доступен под открытой лицензией BSD-3, тем не менее движок слишком сложный, чтобы пытаться переписывать его под себя или разбираться в его устройстве, так что тут лучше поможет документация.

Для этого достаточно в настройках сборки выбрать соответствующий пункт. В этом списке Unity оказался, поскольку существует возможность собрать проект на нём под WebGL.

Поэтому данный вариант не пользуется популярностью и я не стану его подробно рассматривать. Тем не менее WebGL версия Unity в силу особенностей своей архитектуры (трансляция кода из C# в С++ и далее в JavaScript), имеет ряд проблем с производительностью, потреблением памяти и работоспособностью на мобильных устройствах, и не похоже, что разработчики собираются с этим что-то делать в ближайшее время.

Сравнение производительности

Сравним производительность движков по тому, как они справляются с обработкой коллизий большого количества объектов. Используемый браузер — Firefox 64.0.2 x64.

Движок

fps при обработке 100 объектов

fps при обработке 500 объектов

fps при обработке 1000 объектов

ammo.js

40-50

25-27

15-25

cannon.js

30-40

20-25

15-20

oimo.js

45-55

35-40

35-40

По результатам тестов Oimo.js показывает лучшую производительность.

Кроме того заметно, что производительность всех сравниваемых движков довольно невелика, так что данные решения подойдут для написания далеко не каждой игры, но зато хорошо подойдут для создания небольших демо. Разумеется, эти результаты не дают адекватной оценки производительности, так как зависят от множества сторонних факторов, но полноценное исследование потребовало бы куда больше времени да и я такой цели себе не ставил.

Вывод

В целом, выбор конкретного движка зависит от поставленной задачи. Если требуется простой в понимании и легко осваиваемый движок — хорошо подходит Сannon.js или Oimo.js. Если требуется больше функционала, лучше использовать Ammo.js. В определённых ситуациях, если большая производительность не требуется, можно попробовать использовать Unity.


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

В MIT научились передавать звук с помощью лазера

Группа исследователей из MIT представила новый метод передачи направленного звука при помощи лазера. Под катом, рассказываем, на чем построена эта технология. Фото PxHere / PD Лазер для передачи звука Технология направленного звука, способная формировать аудиопоток, слышимый в небольшой области пространства, ...

Ускоряем неускоряемое или знакомимся с SIMD

Есть класс задач, которые нельзя ускорить за счёт оптимизации алгоритмов, а ускорить надо. В этой практически тупиковой ситуации к нам на помощь приходят разработчики процессоров, которые сделали команды, позволяющие выполнять операции на большим количеством данных за одну операцию. В случае ...