Порівняння фізичних рушіїв JavaScript 2026 — Cannon-es, Rapier, Ammo.js, OimoPhysics
Вибір фізичного рушія для проєкту на Three.js передбачає компроміси між розміром бандла, якістю симуляції, затримкою запуску WASM, ергономікою API та підтримкою обмежень. Цей довідник охоплює чотири найпоширеніші варіанти плюс нові альтернативи, із фрагментами коду, що показують мінімальну інтеграцію кожного.
1. Таблиця порівняння можливостей
| Можливість | Cannon-es | Rapier.jsWASM | Ammo.jsWASM | OimoPhysics |
|---|---|---|---|---|
| Мова | TypeScript | Rust → WASM | C++ Bullet → WASM | JavaScript |
| Розмір бандла (gzip) | ~55 KB | ~180 KB | ~750 KB | ~45 KB |
| Тверді тіла | ✓ | ✓ | ✓ | ✓ |
| Опуклі форми | ✓ | ✓ | ✓ | △ обмежено |
| Увігнуті (trimesh) | △ лише статичні | ✓ | ✓ | ✗ |
| З’єднання/обмеження | ✓ базові | ✓ повні | ✓ повні (Bullet) | △ базові |
| М’які тіла / тканина | ✗ | ✗ | ✓ (Bullet) | ✗ |
| CCD (запобігання тунелюванню) | △ за порогом | ✓ | ✓ | ✗ |
| Детермінований повтор | ✗ | ✓ (Rust) | △ | ✗ |
| Типи TypeScript | ✓ нативні | ✓ згенеровані | △ від спільноти | △ |
| Допоміжна бібліотека для Three.js | cannon-es | @dimforge/rapier3d | three/examples/jsm | — |
| Продуктивність (10 тис. тіл) | ~45 fps | ~58 fps | ~50 fps | ~52 fps |
| Рекомендація | Початківцям | Продакшн | М’які тіла | Застаріле |
Показники продуктивності — приблизні для 1000 динамічних боксів, десктопний Chrome, MacBook M2. △ = часткова підтримка.
2. Cannon-es
cannon-es — це форк оригінального cannon.js, який підтримує спільнота, переписаний на TypeScript. Це найзручніший для початківців варіант, що використовується в симуляціях цього сайту.
- Чистий JS/TS — без WASM, без кроку збирання, працює з імпортом через CDN
- Чудова документація та багато прикладів для Three.js онлайн
- Обмеження: немає динаміки увігнутих trimesh, базовий вибір з’єднань, немає детермінізму
// Імпорт через CDN (ES-модуль)
import * as CANNON from 'https://cdn.jsdelivr.net/npm/cannon-es@0.20.0/dist/cannon-es.js';
const world = new CANNON.World({ gravity: new CANNON.Vec3(0, -9.82, 0) });
const body = new CANNON.Body({
mass: 1,
shape: new CANNON.Box(new CANNON.Vec3(0.5, 0.5, 0.5)),
position: new CANNON.Vec3(0, 5, 0),
});
world.addBody(body);
// Синхронізуємо меш Three.js щокадру
mesh.position.copy(body.position);
mesh.quaternion.copy(body.quaternion);
3. Rapier.js (WASM)
Rapier написаний на Rust, скомпільований у WebAssembly й спроєктований із нуля заради коректності, продуктивності та детермінізму. Це найкращий вибір для продакшн-ігор і симуляцій, що потребують точного CCD та складних обмежень.
- У ~3–4 рази швидший за Cannon-es для великих сцен (виграє від SIMD WASM)
- Повний CCD, усі типи з’єднань (обертове, призматичне, фіксоване, сферичне), карта висот
- Детермінований на різних платформах — однакова послідовність чисел із рухомою комою при кожному запуску
- Потребує асинхронної ініціалізації WASM (await RAPIER.init())
import RAPIER from 'https://cdn.skypack.dev/@dimforge/rapier3d-compat';
await RAPIER.init();
const gravity = { x: 0, y: -9.81, z: 0 };
const world = new RAPIER.World(gravity);
const bodyDesc = RAPIER.RigidBodyDesc.dynamic().setTranslation(0, 5, 0);
const rigidBody = world.createRigidBody(bodyDesc);
const colliderDesc = RAPIER.ColliderDesc.cuboid(.5, .5, .5);
world.createCollider(colliderDesc, rigidBody);
// Робимо крок світу
world.step();
const pos = rigidBody.translation(); // { x, y, z }
@pmndrs/cannon та
@react-three/rapier надають декларативні прив’язки для
React Three Fiber. Для ванільного Three.js синхронізація ручна (так
само, як у патерні Cannon-es вище).
4. Ammo.js (Bullet Physics)
Ammo.js — це компіляція через Emscripten C++-бібліотеки Bullet Physics — того самого рушія, що використовується в Blender, Maya та багатьох AAA-іграх. Він надає найширший набір можливостей, включно з м’якими тілами, симуляцією тканини та динамікою транспорту.
- Повний API Bullet доступний у JS (хоч і з прив’язками у стилі C)
- Найбільший бандл (~750 KB gzip) і найповільніший запуск (WASM + велика купа)
- Симуляція м’яких тіл і тканини недоступна в жодному іншому веброзв’язку
-
Приклади Three.js містять помічник
examples/jsm/physics/AmmoPhysics.js
Ammo.destroy()
потрібен для об’єктів купи). Це робить його значно багатослівнішим за
Cannon-es чи Rapier. Використовуйте його, коли вам конкретно потрібні
м’які тіла або фізика транспорту.
5. OimoPhysics
OimoPhysics — це чистий JavaScript-порт Java-рушія Oimo Physics. Найменший бандл, пристойна продуктивність для простих сцен, але обмежені можливості й відсутність активної розробки з 2016 року.
- Підходить для застарілого коду та дуже малих бюджетів бандла
- Немає trimesh, CCD та просунутих обмежень
- Не рекомендований для нових проєктів
6. Як обрати
- Перший проєкт / навчання: Cannon-es — найкраща документація, найбільше прикладів, без складнощів WASM
- Продакшн-гра / симуляція: Rapier.js — найшвидший, детермінований, повна підтримка обмежень
- Тканина або м’які тіла: Ammo.js — єдиний варіант із розв’язувачем м’яких тіл Bullet
-
Стек React Three Fiber:
@react-three/rapierабо@react-three/cannon - Рідини / гранульовані на основі частинок: власний SPH чи MPM — готової до продакшну JS-бібліотеки поки не існує
jolt-physics). Ранні бенчмарки показують удвічі більшу за
Rapier швидкість для великих сцен. Стежте за зрілістю у 2026 році.