| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- <!DOCTYPE html>
- <html lang="zh">
- <head>
- <meta charset="utf-8">
- <title>物理</title>
- <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
- <meta name="twitter:card" content="summary_large_image">
- <meta name="twitter:site" content="@threejs">
- <meta name="twitter:title" content="Three.js - 物理">
- <meta property="og:image" content="https://threejs.org/files/share.png">
- <link rel="shortcut icon" href="../../files/favicon_white.ico" media="(prefers-color-scheme: dark)">
- <link rel="shortcut icon" href="../../files/favicon.ico" media="(prefers-color-scheme: light)">
- <link rel="stylesheet" href="../resources/lesson.css">
- <link rel="stylesheet" href="../resources/lang.css">
- <link rel="stylesheet" href="/manual/zh/lang.css">
- <script type="importmap">
- {
- "imports": {
- "three": "../../build/three.module.js"
- }
- }
- </script>
- </head>
- <body>
- <div class="container">
- <div class="lesson-title">
- <h1>物理</h1>
- </div>
- <div class="lesson">
- <div class="lesson-main">
- <p>
- 物理引擎可以在 3D 场景中模拟重力、碰撞、受力等物理现象。
- 在常规 three.js 场景中,我们通常直接修改对象位置和旋转;
- 而在使用物理引擎时,会额外维护一个并行的“物理世界”,
- 刚体在其中响应力和碰撞。然后每帧把 three.js 网格与物理刚体状态同步,
- 从而呈现出“真实物理”效果。
- </p>
- <p>
- 需要注意的是,物理引擎不一定要每帧更新。为了保持模拟稳定,
- 通常会采用固定时间步。比如游戏循环运行于 60fps,
- 物理更新运行于 30fps(1/30 秒),
- 同时每帧使用物理引擎的最新状态更新 three.js 网格变换(位置、旋转等)。
- </p>
- <p>
- 物理模拟尤其适用于游戏、交互可视化,以及任何需要真实对象行为的应用,
- 例如下落、弹跳、滑动等效果。
- </p>
- <h2>集成方式</h2>
- <p>
- 在 three.js 项目中集成物理引擎,主要有三种方式:
- </p>
- <h3>1. 使用 three.js 物理插件</h3>
- <p>
- Three.js 在 <i>examples/jsm/physics</i> 目录中为多个常见物理引擎提供了封装类。
- 这些插件可简化接入流程,完成物理世界初始化与网格同步。
- </p>
- <p>
- 可用插件包括:
- </p>
- <ul>
- <li><b>AmmoPhysics:</b>Ammo.js(Bullet 物理)的封装。</li>
- <li><b>JoltPhysics:</b>Jolt Physics 的封装。</li>
- <li><b>RapierPhysics:</b>Rapier 的封装。</li>
- </ul>
- <p>
- 这些插件屏蔽了大量底层复杂性。对于常规需求,它们是最快的入门路径之一。
- </p>
- <h4>
- 示例
- </h4>
- <ul>
- <li><a href="https://threejs.org/examples/physics_ammo_instancing.html" target="_blank">physics / ammo / instancing</a></li>
- <li><a href="https://threejs.org/examples/physics_jolt_instancing.html" target="_blank">physics / jolt / instancing</a></li>
- <li><a href="https://threejs.org/examples/physics_rapier_instancing.html" target="_blank">physics / rapier / instancing</a></li>
- </ul>
- <h3>2. 使用第三方 JS/TS 物理库</h3>
- <p>
- 许多物理引擎直接由 JavaScript / TypeScript 编写,
- 与 Web 生态集成较容易。像 <b>cannon-es</b> 这类库因轻量且接入简单而常被采用。
- </p>
- <p>
- 使用这类库时,你需要自己创建物理世界和刚体,
- 并在动画循环中手动把刚体的位置、四元数同步到 three.js 网格。
- </p>
- <h4>
- 项目
- </h4>
- <ul>
- <li><b><a href="https://github.com/pmndrs/cannon-es" target="_blank">cannon-es</a></b>:纯 JS/TS 的轻量 3D 物理引擎,MIT 协议。看起来维护已不活跃(最近提交距今较久)。</li>
- <li><b><a href="https://github.com/schteppe/cannon.js" target="_blank">cannon.js</a></b>:纯 JavaScript 的轻量 3D 物理引擎,MIT 协议。已基本停止维护。建议优先使用其较新的分支 cannon-es。</li>
- <li><b><a href="https://github.com/lo-th/phy" target="_blank">phy</a></b>:面向 three.js 的纯 JavaScript 物理引擎,MIT 协议。当前仍在维护。</li>
- <li><b><a href="https://github.com/lo-th/Oimo.js" target="_blank">Oimo.js</a></b>:纯 JavaScript 轻量 3D 物理引擎,已不再维护。作者建议改用 phy。</li>
- </ul>
- <p>
- 另外还有一类“看似 JS/TS、实则调用外部引擎”的方案,例如:
- </p>
- <ul>
- <li><b><a href="https://github.com/chandlerprall/Physijs" target="_blank">Physijs</a></b>:底层调用 ammo.js,并借助 Web Worker 在独立线程处理物理,MIT 协议。维护不活跃(最近提交距今多年)。</li>
- <li><b><a href="https://github.com/enable3d/enable3d" target="_blank">enable3d</a></b>:基于 ammo.js 的 three.js 3D 物理框架,LGPL-3.0 协议。看起来仍在维护。</li>
- </ul>
- <h3>3. 引入基于 WASM 的引擎</h3>
- <p>
- 如果你需要更高性能、稳定性和精度(尤其复杂模拟),
- 可以选择 C++/Rust 等语言编写并编译为 WebAssembly(WASM)的物理引擎。
- 例如 <b>Ammo.js</b>(Bullet 的移植版)和 <b>Rapier</b> 都属于这一类。
- </p>
- <p>
- 这种方式通常功能最完整、性能最好,但接入成本更高,
- 需要处理 WASM 内存管理及与物理 API 的直接交互。
- </p>
- <h4>
- 示例
- </h4>
- <ul>
- <li><a href="https://threejs.org/examples/physics_ammo_break.html" target="_blank">physics / ammo / break</a></li>
- <li><a href="https://threejs.org/examples/physics_ammo_cloth.html" target="_blank">physics / ammo / cloth</a></li>
- <li><a href="https://threejs.org/examples/physics_ammo_rope.html" target="_blank">physics / ammo / rope</a></li>
- <li><a href="https://threejs.org/examples/physics_ammo_terrain.html" target="_blank">physics / ammo / terrain</a></li>
- <li><a href="https://threejs.org/examples/physics_ammo_volume.html" target="_blank">physics / ammo / volume</a></li>
- </ul>
- <h4>
- 项目
- </h4>
- <ul>
- <li><b><a href="https://github.com/jrouwe/JoltPhysics" target="_blank">JoltPhysics</a></b>:面向多核的刚体物理与碰撞检测库,C++ 编写,MIT 协议,活跃维护。已在《Horizon Forbidden West》《Death Stranding 2》等知名作品中得到验证,并获得 Godot 游戏引擎官方支持。</li>
- <li><b><a href="https://github.com/NVIDIA-Omniverse/PhysX" target="_blank">PhysX</a></b>:NVIDIA 提供的工业级实时 3D 物理引擎,BSD-3-Clause 协议,稳定且持续维护。</li>
- <li><b><a href="https://github.com/dimforge/rapier" target="_blank">Rapier</a></b>:注重性能的 2D/3D 物理引擎,Rust 编写,MIT 协议,活跃维护。</li>
- <li><b><a href="https://github.com/bulletphysics/bullet3" target="_blank">Bullet</a></b>:
- 用于 VR、游戏、视觉特效、机器人、机器学习等场景的实时碰撞检测与多物理模拟库,C++ 编写,ZLIB 协议。维护状态可能不活跃。</li>
- </ul>
- <p>
- 其中一些跨平台 3D 物理引擎已有可直接使用的 WASM 版本,例如:
- </p>
- <ul>
- <li><b><a href="https://github.com/jrouwe/JoltPhysics.js" target="_blank">JoltPhysics.js</a></b>:使用 Emscripten 将 JoltPhysics 移植到 JavaScript,MIT 协议,当前维护中。</li>
- <li><b><a href="https://github.com/fabmax/physx-js-webidl" target="_blank">physx-js-webidl</a></b>:NVIDIA PhysX 的 JavaScript WASM 绑定,MIT 协议,当前维护中。</li>
- <li><b><a href="https://github.com/dimforge/rapier.js" target="_blank">Rapier.js</a></b>:Rapier 的官方 JavaScript 绑定,Apache-2.0 协议,活跃维护。</li>
- <li><b><a href="https://github.com/kripken/ammo.js" target="_blank">Ammo.js</a></b>:使用 Emscripten 将 Bullet 直接移植到 JavaScript,维护不活跃(最近提交距今多年),采用类似 MIT 的宽松自定义协议。</li>
- </ul>
- </div>
- </div>
- </div>
- <script src="../resources/prettify.js"></script>
- <script src="../resources/lesson.js"></script>
- </body>
- </html>
|