01 / 23
← → 翻页 · F 全屏
Hippocampal · Research Talk
How to Build a
Physics Engine
物理引擎是怎么炼成的 —— 拆解它的 anatomy、回顾 history,
再横评四大引擎:MuJoCo · Genesis · Unreal · Unity
Roadmap · 路线图
今天讲什么
Part 1 · Anatomy
解剖结构
每个引擎都跑的那个 loop:forces → integrate → collide → solve → update。
Part 2 · History
发展历史
从 Havok 到 Genesis,以及物理引擎分裂出的 两种文化。
Part 3 · The Big Four
四大引擎
语言、工作流程、横向对比 —— 它们到底差在哪、为什么。
目标:听完能把任何一个引擎放到这张地图上。
The Hook · 开场
全程,我们就盯着这一个盒子
从 1 米高扔下一个盒子 → 砸到地板 → 弹一下 → 停稳。
要画出这一秒钟,引擎把同样的 5 个步骤重复了约 60 次。
接下来的每一页,我们就跟着这个盒子,看引擎到底在每一步做了什么。
地球上每个 rigid-body engine,从玩具到 MuJoCo,跑的都是这同一个 loop。
Part 1 · Anatomy
The Loop —— 每步都跑一遍
⚠️ 注意:这是所有 rigid-body engine 通用的流程,不是某一个引擎专有的。
01 · Forces
施加力
gravity、motor、spring、用户输入 → 转成 force & torque。
02 · Integrate
积分
力改变 velocity 和 position,推进一个极小的 time step。
03 · Collide
碰撞检测
broad phase 粗筛,narrow phase 算出精确接触点。
04 · Solve
求解约束
阻止穿模,enforce joint 和 friction。
05 · Update
更新状态
提交新的位置/速度 → 渲染这一帧。
接下来重点拆开 step 2、3、4 —— 真正的工程难点都在这里。
Anatomy · 起点 — The State
开始之前:引擎眼里的盒子是一组数字
📦 拿盒子说引擎根本不认识"盒子"。它只存一组数字来描述这个盒子,模拟 = 每一小步把这组数字更新一次。
会变的(state · 状态)
- Position 位置 —— 盒子在哪里 (x, y, z)。
- Orientation 朝向 —— 盒子转了多少、怎么倾斜。
- Linear velocity 线速度 —— 下落多快。
- Angular velocity 角速度 —— 转多快。
不变的(属性 · 物理常量)
- Mass 质量 —— 多重,越重越难被推动 (
F = ma)。
- Inertia 惯性 —— 质量怎么分布,决定多难被转动。
- 由 Newton–Euler equations 把"力"换算成"位置/朝向怎么变"。
一句话:整个模拟,就是不停地改这几个数字。
Anatomy · Step 2 — Integration · 让盒子动起来
把"力"变成"运动"
📦 拿盒子说gravity 把盒子往下拉。每过一个极小的时间步 dt(比如 1/60 秒):先算盒子的新速度(被重力加快),再算新位置(下落一点点)。重复 → 盒子越落越快。这一步就叫 integration(积分)。
# Explicit Euler —— 会"爆炸"
pos += vel * dt
vel += (force/mass) * dt
# 先动位置、用的是"旧"速度
# Semi-implicit Euler —— 稳定
vel += (force/mass) * dt
pos += vel * dt
# 先更新速度,再用"新"速度动位置
Anatomy · Step 3 — Collision Detection · 碰到了吗
盒子撞到地板了吗?撞在哪?
📦 拿盒子说盒子在下落,引擎每一步都要问两个问题:① 它碰到地板了吗? ② 如果碰了,碰在哪、压进去多深? 为了快,这件事分两步做。
① Broad phase · 粗筛
先便宜地排除"明显碰不到"的
给每个物体套一个简单方框,快速判断"盒子大概在不在地板附近"。远处的墙?一眼排除。
为什么要这步:几千个物体两两检测太慢(O(n²)),先粗筛掉绝大多数。
做法:Sweep-and-prune、Spatial grid、BVH。
② Narrow phase · 精算
对剩下的几个,算精确接触
确认真的接触后,算出 具体哪几个角接触、压进去多深、沿哪个方向 —— 这些是下一步 solver 要用的。
做法:GJK(有没有重叠)→ EPA(多深、哪个方向)。
Contact manifold:盒子平放有 4 个角接触 → 要 4 个接触点,只取 1 个会翻倒。
Anatomy · Step 4 — Solve · 最难的一步
别让盒子陷进地板
📦 拿盒子说上一步发现:盒子已经陷进地板一点点(penetration · 穿透)。这一步要做两件事 —— ① 把它推回地面上;② 决定它该弹起来还是停住。
没有这一步会怎样?盒子直接穿过地板掉下去。
这里的"约束 constraints"是什么
- 地板 = 一条约束:盒子不准进入地板。
- Restitution 弹性 → 决定弹多高;friction 摩擦 → 决定会不会滑。
- (机器人里)joint 关节 = 约束:连杆不准被拉断。
怎么解(一句话各表)
- Impulse —— 给盒子一个瞬间反向速度,让它停下/弹起。
- Sequential Impulses / PGS —— 反复扫每个接触点,一点点逼近正确解。Box2D 的核心。
- Soft constraint / convex —— 允许极小穿透,换来稳定和速度。MuJoCo 的路子。
贯穿全场的思路 → 别去解那个精确但极难(NP-hard)的问题,而是把它重塑成一个永远能快速解出的问题 —— 这就是 "soft" 和 MuJoCo convex contact 的核心思想。
Anatomy · Step 5 + 重复 — The Loop
把这 4 步,每秒重复 60 次
📦 拿盒子说力 → 积分 → 碰撞 → 求解,跑完这 4 步 = 盒子的世界前进了 1/60 秒。要画出 1 秒的弹跳,就把它重复 60 次。这就是 the loop。
Fixed timestep · 固定步长
每步固定 1/60 秒,和"画面帧率"分开。
否则:电脑快慢不同,同一个盒子弹出来的结果都不一样。
Substepping · 细分
盒子掉得特别快时,把一步切成几小步。
否则:盒子可能一步就"穿过"地板,碰撞没被发现。
Determinism · 可复现 (难)
同一个盒子扔两次,能弹得一模一样吗?很难。
浮点 floating-point 运算跨 CPU/线程有微小误差,会被放大。联网游戏要"两台电脑算出同样结果"就卡在这。
经典阅读:Glenn Fiedler,"Fix Your Timestep!"
Part 2 · History
物理引擎的 ~25 年
2000Havok —— 第一个主流商业 middleware。Half-Life 2 证明游戏能有真实刚体物理。
2001ODE —— 早期开源刚体引擎,研究与游戏广泛使用。
2004–08PhysX —— NovodeX → Ageia(2006 出过物理硬件卡)→ NVIDIA(2008)搬上 GPU。
~2006Bullet —— 开源常青树,横跨游戏、影视、机器人(PyBullet)。
2012MuJoCo —— 为精确的 model-based control 和机器人而生,成为 RL 标准。
2024Genesis —— generative、GPU-native、多 solver,"world simulator"时代。
Part 2 · The Big Idea
物理引擎的两种"文化"
Real-time / Games
Plausible & Fast(逼真且快)
- 看起来可信,毫秒级跑完。
- 稳定与视觉效果优先于物理真实。
- Maximal coordinates + 迭代 impulse solver。
- Havok · PhysX · Bullet · Unity · Unreal Chaos
Scientific / Robotics
Accurate & Analyzable(精确可分析)
- 为 control、planning、RL 提供正确 dynamics。
- 完整 friction-cone contact,可复现。
- Generalized coordinates + convex optimization。
- MuJoCo · Drake · Pinocchio · Dojo
2024+ 融合: Genesis 与 NVIDIA Newton 采用 MJWarp(源自 MuJoCo 的 GPU 后端)—— MuJoCo 级精度 加上 大规模并行 GPU 速度。
Part 3 · Foundation
它们用什么语言写、你用什么驱动
引擎核心(为了快)和你写的代码(为了好用)往往是两种不同的语言。
| 引擎 | 核心 written in | 你用什么驱动它(user-facing) | 偏向 |
| MuJoCo | C / C++ | MJCF (XML) 描述模型 + Python API(GPU 版 MJX 用 JAX) | Physics |
| Genesis | Python(经 Taichi 编译到 GPU) | Python —— 纯 Python,最易上手 | Physics |
| Unreal | C++ | C++ + Blueprints(可视化脚本) | Graphics |
| Unity | C++ 引擎 | C# 脚本(DOTS:C# + Burst 编译) | Graphics |
规律: 偏 physics 的(MuJoCo、Genesis)走 Python 路线,对接 ML/研究;偏 graphics 的(Unity、Unreal)走 C# / C++ + 编辑器,对接游戏/影视。
Part 3 · Workflow
用一个引擎跑出一个场景 —— 流程图
STEP 1
Define model定义场景/模型
写 code 或 XML:物体、joint、相机。
→
STEP 2
Configure physics配置物理参数
mass、friction、gravity、timestep。
→
STEP 3
Simulate跑模拟
引擎跑那个 loop:force→integrate→collide→solve。
→
STEP 4
Render / Output渲染/输出
出图像、视频、或 trajectory 数据。
→
✅ 效果
Result最终成果
物理正确的动画 / 训练数据 / 游戏画面。
🤖 AI(如 Claude Code)能在每一环 assist:
Step 1帮你写 scene/MJCF/CadQuery 代码,把"一句话"变成模型。
Step 2调参 & debug:"为什么会爆炸/穿模?",建议 friction/timestep。
Step 3写 simulation loop、RL 训练管线、批量跑 1000 个场景。
Step 4写 render 配置、output writer、验证脚本(对不对)。
👉 这正是 Hippocampal 的 generators 在做的事 —— 人判断"对不对",AI 负责"快速写和改"。
Part 3 · The Big Four
四大引擎
MuJoCo
机器人 & RL。精确,soft convex contact。
Genesis
generative、GPU-native、多 solver(2024)。
Unreal · Chaos
实时破坏 & 电影级视觉效果。
Big Four · 01
MuJoCo C/C++ · Physics
Big Four · 02
Genesis Python+Taichi · Physics
Big Four · 03
Unreal · Chaos C++ · Graphics
Big Four · 04
Unity C# · Graphics
Part 3 · Side by Side
四个引擎,一张地图
| 维度 Axis | MuJoCo | Genesis | Unreal · Chaos | Unity |
| 偏 Physics / Graphics | Physics | Physics | Graphics | Graphics |
| 用途 Purpose | 机器人 / RL | 机器人 + 生成数据 | 游戏 + 影视 | 游戏(移动→AAA) |
| 优先 Priority | 精度 | 精度 + 规模 | 视觉效果 | 易用性 |
| 语言 Language | C/C++ · Python | Python · Taichi | C++ · Blueprint | C# · Burst |
| Contact 模型 | soft convex | 多 solver / IPC | iterative PBD | impulse / PGS |
| GPU | MJX (JAX) | GPU-native | 实时 | DOTS / Burst |
| Differentiable | ~(analytic) | Yes | No | No |
| License | Apache-2.0 | 开源 | 商业闭源 | 商业闭源 |
Leader 的总结: Genesis & MuJoCo 更偏 physics(精确动力学,为 control/RL);Unity & Unreal 更偏 graphics(实时画面,为游戏/影视)。
Choosing · 怎么选
换成你会选哪个?
训练机器人走路 →
MuJoCo(或 Genesis)。精确 contact、并行 RL、sim-to-real。
大规模生成物理训练数据 →
Genesis。多 solver + prompt→scene 生成管线。
大片里一栋楼塌掉 →
Unreal Chaos。电影级破坏,艺术家工具链。
跨平台手机游戏 →
Unity。最易用、生态最大、到处能发。
没有"最好"的引擎,只有针对 精度 vs 速度 vs 视觉 vs 易用 的正确取舍。
Wrap-up · 总结
记住三件事
- ① 一个 loop,处处通用。 forces → integrate → collide → solve → update。学透一次,任何引擎都能看懂。
- ② 诀窍是"重塑难题"。 semi-implicit Euler、两段式 collision、soft convex contact —— 都是用一点点精度,换稳定与速度。
- ③ 先看文化,再看工具。 游戏求 逼真且快(graphics);科研求 精确可分析(physics)—— 2024 起在 GPU 上开始融合。
为什么这跟我们有关: Hippocampal 的 generators 跑在 MuJoCo + Genesis 上批量产出物理正确的视频 —— 正是"科研文化 + GPU 规模化"的前沿。
Go Deeper · 延伸
Demos & Resources
Thank You · 谢谢
Questions?
forces → integrate → collide → solve → update。
这就是一个 physics engine,其余的全是你做了什么取舍。