文章目录
概览
一,物理对象与形状
1.1 对象 Actor
一般来说,游戏中的对象(Actor)分为以下四类:
- 静态对象 Static Actor:不动的物体,环境桌子等
- 动态对象 Dynamic Actor :可能受到力/扭矩/冲量的影响,比如主控角色等
- 检测器 Trigger:与GamePlay高度相关的触发开关,比如走进范围内就触发效果的这个“范围”
- 运动学对象Kinematic Actor :忽略物理法则表现的对象,根据游戏的需要由游戏逻辑控制,比如跑步动画。但反物理的表现经常出现bug,比如碰到一个箱子结果箱子飞了
1.2 对象形状Actor Shape
因为真实世界中物体形状是非常复杂的,其物理求交也非常复杂,所以游戏中通常会用简单形状的物理对象来替代表达,常见形状有:
- 球Spheres:各种类球形物体
- 胶囊Capsules:角色
- 盒Box:建筑家具等
- 凸包体Convex Mesh:精细一点的物体比如岩石
- 三角网格Triangle Mesh:如精细一点的建筑(静态)
- 高程图形成的地形Height Fields:地形
- 用这种简单几何体去模拟物理对象时有两个原则:
- 形状差不多就好,不用完美贴合
- 简单性。几何形状越简单越好(比如避免用Triangle Mesh),几何体个数越少越好。
- 这里课件里有个很漂亮的石头受光焦散图,放一下:
二,力与运动
- 物理概念:
- 质量和密度 Mass and Density
- 质心(做载具时很重要,比如卡车)Center of Mass
- 摩擦和恢复(弹性) Friction & Restitution
- 力Forces:有直接的拉力、重力、摩擦力以及Impulse 冲量(比如爆炸导致的冲击力,其实是力x时间)两种
2.1 牛顿定律
高中知识就不记了
2.2 欧拉法
2.2.1 显式欧拉法Explicit (Forward) Euler’s Method
这是与积分直觉最接近的算法,思路简单,即下一时间的速度和位置都用上一时间的量去计算:


- 但由于显示欧拉法一直用当前状态值去预估未来状态,在实际模拟时Δ t 不会无限小,会有误差导致能量不守恒(变大),如上右图,在模拟绕点旋转的时候速度越来越快逐渐甩出去,能量也凭空变多,导致能量爆炸。(Δ t 很小可以避免,但实际做不到)
2.2.2 隐式欧拉法 Implicit (Backward) Euler’s Method
思路是用未来的力和速度去求未来的位置,但未来的力怎么计算呢,需要假设力是位置的函数去反向计算,如下图:


- 如图,隐式欧拉法的能量虽然也不守恒,但是至少能量是衰减的,符合现实物理规律(受空气阻力摩擦力影响等),因此在游戏中更容易接受。
- 但其也有计算成本高(反向计算未来值)并且运动非线性时难以计算的缺点
2.2.3 半隐式欧拉法 Semi-implicit Euler’s Method
半隐式欧拉法就是结合了前两种方法,新速度用旧的力去算,新位置用新速度算:


- 前提假设:力是不随着位置改变的(很危险的假设,实际上力跟物体位置是相关的,比如橡皮筋弹射过程)。
- 优点:大部分稳定、计算简单有效、随着时间的推移能够保存能量
- 缺点:在做一些sin cos等运动时,积分出来的周期会比正确值长一点点,所以在相位上会有偏移差
三,刚体动力学
之前的内容都是把物体看作一个质点,但真实世界中大部分物体是有形状的,即刚体(柔性模拟另说)。刚体动力学中比普通质点的计算多一些概念,比如自转、旋转等,概念对应见下图:
这part在部分场景下很重要,比如台球游戏,不仅需要旋转还要自转还要移动,了解即可,详情见高中物理
四,碰撞检测
碰撞检测一般分为两个阶段:
- Broad phase 初筛 – 利用AABB判断刚体有没有相交
- Narrow phase – 计算详细碰撞信息(碰撞点、方向、深度等)
4.1 Broad phase 初筛
常用有两种方法:
-
BVH Tree – 动态更新成本低,方法成熟
-
Sort and Sweep – 比BVH更快,先沿轴周把每个AABB边界大小值排序,再逐个扫描,如果minmax没按照顺序来就有可能发生了碰撞这时再去判断另一个轴上的情况。这种排序算法可以把静态物体排好序后,只更新动态物体的位置(插入排序),这种方法更快。