中EN
概念页

数值积分

Numerical Integration

游戏中的力是交互的、无法事先预测的,运动方程(常微分方程)几乎没有解析解,所以物理引擎采用数值积分:以大致恒定的时间步长 Δt\Delta t 逐步推进,由当前时刻 t1t_1 的 r(t1)\mathbf r(t_1)、v(t1)\mathbf v(t_1) 和力函数 F(t,r,v)\mathbf F(t,\mathbf r,\mathbf v) 求出 t2=t1+Δtt_2=t_1+\Delta t 时的位置与速度。衡量方法好坏看收敛性、阶、稳定性三项。显式欧拉最简单但误差大、不稳定;GEA 认为交互游戏中最常用的大概是 Verlet,尤其是速度 Verlet(GEA4 卷 II 14.4.4)。

显式欧拉 (Explicit Euler)

新手最常写的方法:把"米每秒"乘以 Δt\Delta t 变成"米每帧",加到当前位置上(卷 II 14.4.4.1):

r(t2)=r(t1)+v(t1)Δt(14.5),v(t2)=v(t1)+Fnet(t1)mΔt(14.6)\mathbf r(t_2)=\mathbf r(t_1)+\mathbf v(t_1)\Delta t\quad(14.5),\qquad \mathbf v(t_2)=\mathbf v(t_1)+\frac{\mathbf F_{net}(t_1)}{m}\Delta t\quad(14.6)

两种理解:

  • 线性外推:假设步内速度恒定,用 t1t_1 处的斜率 v(t1)\mathbf v(t_1) 直线外推到 t2t_2(图 14.23)。速度大致恒定时效果尚可。
  • 有限差分近似导数:把 dr/dtd\mathbf r/dt 换成 Δr/Δt\Delta\mathbf r/\Delta t,即 v(t1)≈r(t2)−r(t1)t2−t1\mathbf v(t_1)\approx\frac{\mathbf r(t_2)-\mathbf r(t_1)}{t_2-t_1}。只在速度恒定或 Δt→0\Delta t\to0 的极限下精确成立。

数值方法的三项性质

(卷 II 14.4.4.2)

  • 收敛性 (Convergence):Δt→0\Delta t\to0 时近似解是否越来越接近真实解。
  • 阶 (Order):误差通常正比于 Δt\Delta t 的某次幂,用大 O 记号表示;误差项为 O(Δtn+1)O(\Delta t^{n+1}) 的方法称为 n 阶方法。注意这里的 O(Δtn+1)O(\Delta t^{n+1}) 是单步(局部)截断误差;固定时间区间要走 T/ΔtT/\Delta t 步,累积的全局误差是 O(Δtn)O(\Delta t^{n}),这正是叫"n 阶"的原因(GEA 未区分两者;见 Wikipedia "Truncation error (numerical integration)"、Hairer/Nørsett/Wanner《Solving Ordinary Differential Equations I》II.3)。
  • 稳定性 (Stability):数值解会不会随时间"平静下来"。方法往系统里加入能量,速度最终会"爆炸",系统不稳定;方法移除能量则有整体阻尼效果,系统稳定。

用泰勒展开求阶:精确解展开为

r(t2)=r(t1)+r˙(t1)Δt+12r¨(t1)Δt2+16r(3)(t1)Δt3+⋯\mathbf r(t_2)=\mathbf r(t_1)+\dot{\mathbf r}(t_1)\Delta t+\tfrac12\ddot{\mathbf r}(t_1)\Delta t^2+\tfrac16\mathbf r^{(3)}(t_1)\Delta t^3+\cdots

减去显式欧拉 r(t2)=r(t1)+r˙(t1)Δt\mathbf r(t_2)=\mathbf r(t_1)+\dot{\mathbf r}(t_1)\Delta t,剩余误差 E=12r¨Δt2+⋯=O(Δt2)E=\tfrac12\ddot{\mathbf r}\Delta t^2+\cdots=O(\Delta t^2),所以显式欧拉是一阶方法,可写成 r(t2)=r(t1)+r˙(t1)Δt+O(Δt2)\mathbf r(t_2)=\mathbf r(t_1)+\dot{\mathbf r}(t_1)\Delta t+O(\Delta t^2)。

其他方法

显式欧拉在游戏中常用于简单的积分任务(速度近似恒定时最好),但误差大、稳定性差,不用于通用动力学模拟。其他方法有后向欧拉(一阶)、中点欧拉(二阶)和 Runge-Kutta 家族,其中四阶 Runge-Kutta (RK4) 尤其流行。GEA 不展开这些方法,只建议从维基百科入手(卷 II 14.4.4.3)。

Verlet 积分

GEA 认为这是当今交互游戏中最常用的数值方法(卷 II 14.4.4.4)。普通 Verlet 的优点:阶高(误差小)、计算简单便宜、一步直接由加速度得到位置(不必先求速度再求位置)。推导:把向前和向后两个泰勒展开相加,奇次项相互抵消:

r(t1+Δt)=2r(t1)−r(t1−Δt)+a(t1)Δt2+O(Δt4)\mathbf r(t_1+\Delta t)=2\mathbf r(t_1)-\mathbf r(t_1-\Delta t)+\mathbf a(t_1)\Delta t^2+O(\Delta t^4)

其中 a(t1)=Fnet(t1)/m\mathbf a(t_1)=\mathbf F_{net}(t_1)/m。式中没有速度;需要速度时可用一个不太精确的近似:v(t1+Δt)=r(t1+Δt)−r(t1)Δt+O(Δt)\mathbf v(t_1+\Delta t)=\frac{\mathbf r(t_1+\Delta t)-\mathbf r(t_1)}{\Delta t}+O(\Delta t)。

速度 Verlet (Velocity Verlet)

更常用。把时间步分成两半,已知 a(t1)=1mF(t1,r(t1),v(t1))\mathbf a(t_1)=\frac1m\mathbf F(t_1,\mathbf r(t_1),\mathbf v(t_1)),分四步(卷 II 14.4.4.5):

  1. r(t1+Δt)=r(t1)+v(t1)Δt+12a(t1)Δt2\mathbf r(t_1+\Delta t)=\mathbf r(t_1)+\mathbf v(t_1)\Delta t+\tfrac12\mathbf a(t_1)\Delta t^2
  2. v(t1+12Δt)=v(t1)+12a(t1)Δt\mathbf v(t_1+\tfrac12\Delta t)=\mathbf v(t_1)+\tfrac12\mathbf a(t_1)\Delta t
  3. a(t2)=1mF(t2,r(t2),v(t2))\mathbf a(t_2)=\frac1m\mathbf F(t_2,\mathbf r(t_2),\mathbf v(t_2))
  4. v(t1+Δt)=v(t1+12Δt)+12a(t1+Δt)Δt\mathbf v(t_1+\Delta t)=\mathbf v(t_1+\tfrac12\Delta t)+\tfrac12\mathbf a(t_1+\Delta t)\Delta t

第 3 步需要下一步的位置和速度。位置已在第 1 步算出,力不依赖速度时信息就齐了;力依赖速度时(如阻尼),就要先近似下一帧速度,例如用显式欧拉。

同样的方法也用于角运动方程,见 刚体动力学。时间步长的选择与游戏循环的关系见 物理引擎与游戏的集成 和 游戏循环与更新方法。

GEA 原书中的问题

  • 式 14.6 写作 v(t2)=v(t1)+Fnet(t)mΔt\mathbf v(t_2)=\mathbf v(t_1)+\frac{\mathbf F_{net}(t)}{m}\Delta t,力的时间参数应为 t1t_1(显式方法用的是当前时刻的力),与 14.4.5.5 二维角动力学的写法 Nnet(t1)N_{net}(t_1) 不一致(已核对渲染页:印刷页 378 式 14.6 确为 Fnet(t)\mathbf F_{net}(t))。
  1. Game_Engine_Architecture_4th_Edtion_Volume_2_-_Jason_Gregory.pdf
  2. Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 14 章 14.4.4 节

相关页面

游戏开发刚体动力学Rigid Body Dynamics游戏物理引擎关心的是动力学:力如何影响运动。它做了两个简化:经典(牛顿)力学(无量子、无相对论效应)和刚体(形状不变)。无约束刚体有 6 个自由度,其运动可以分成互相独立的线性动力学(质心像质点一样平动)和角动力学(绕质心转动)。线性部分是 F=ma 的常微分方程;三维角动力学则以角动量为主变量,并用一个四元数形式的微分方程更新朝向(GEA4 卷 II 14.4)。游戏开发碰撞响应与约束求解Collision Response & Constraint Solving刚体碰撞后,模拟必须让它们做出逼真的反应,并保证一步结束时不再互相穿透,这就是碰撞响应。主流方法有三种:基于牛顿恢复定律的冲量法、像硬阻尼弹簧一样的惩罚力、以及把碰撞当作约束交给通用约束求解器。此外还要处理摩擦、多边形汤上的伪接触(焊接),以及让物体安静下来(休眠与模拟岛)。约束(点对点、铰链、棱柱、布娃娃、动力约束等)限制刚体的自由度;每帧的物理步骤是"积分 → 碰撞检测 → 碰撞解决 → 约束求解"的迭代误差最小化(GEA4 卷 II 14.4.7–14.4.10)。游戏开发游戏循环与更新方法Game Loop & Update Method游戏循环 (Game Loop) 让游戏时间的推进与玩家输入和处理器速度脱钩:每一轮非阻塞地处理输入、更新状态、渲染,并跟踪真实时间来控制节奏;最常推荐的做法是“固定更新步长、可变渲染”。更新方法 (Update Method) 是它的搭档:世界维护一组对象,每个对象实现一个模拟“一帧”行为的 update(),每帧依次调用。两者和组件模式一起常被视为游戏引擎的核心。游戏开发物理引擎与游戏的集成Integrating a Physics Engine into a Game碰撞/物理世界里的刚体只是抽象的数学描述,要通过游戏对象这个中枢,间接连到屏幕上的视觉表现。刚体按谁驱动分三类:物理驱动、游戏驱动(Havok 称 key framed)、固定;Havok 用可在运行时切换的"运动类型"统一表示。每帧更新有固定顺序:先更新游戏驱动刚体、幻影、力、冲量和约束,再步进模拟,然后回读物理驱动对象、查询幻影、执行投射查询。物理宜用恒定的 1/30 或 1/60 秒时间步。GEA 还逐一讨论了子弹、手雷、爆炸、可破坏物、角色移动、相机碰撞和布娃娃的实际做法(GEA4 卷 II 14.5–14.6)。游戏开发 · UE5Chaos 物理与碰撞Chaos Physics & CollisionChaos 是 UE5 的物理与破碎系统。日常最常打交道的是碰撞模型:每个物理体有对象类型 (Object Type) 和对其他类型的 Block/Overlap/Ignore 响应,结果由双方共同决定;Hit 与 Overlap 事件都要显式开启。骨骼网格通过物理资产 (Physics Asset) 获得刚体与约束(布娃娃、物理动画);Chaos 破碎基于几何集合 (Geometry Collection) 的分级断裂、簇阈值、连接图与缓存回放,并能把事件交给 Niagara。物理体用盒/球/胶囊/凸包代理,原理对应游戏数学中的包围体与相交测试。

被这些页面引用1 篇

输入关键词开始搜索

滚轮或双指缩放 · 拖动平移 · 双击放大 / 还原