原文标题:《给我一个物理引擎,我也能“预测”世界杯?》
世界杯正如火如荼地进行,而大力神杯终究会花落谁家,成为了每届世界杯都被人们津津乐道的话题。许多专业机构也不甘落后,纷纷用自己的专业模型和数据进行分析,给出了每支球队夺冠的赔率。但你有没有想过,不要 998,只要一个物理引擎,你也可以在家“预测”世界杯?
此预测非彼预测
看到这个小标题,想必同学们应该也猜到了,小编接下来为大家介绍的既不是像章鱼保罗这样的“神兽”式预测,也不是专业预测机构那样神秘的数据分析。接下来,小编将带领同学们走入的是元宇宙纪元下交互版的世界杯预测世界😎(其实就是带大家一起玩实况啦~)
不知道还有多少同学知道这样一句话呢:“欢迎来到实况足球 8,国际版的游戏世界”🤔实况 8,相信是整整一代人的足球游戏入坑作,想当年小编也曾在其中打造自己的“梦之队”,去驰骋世界赛场,斩获一座座奖杯。
小编再来考一考,有多少同学知道拉普拉斯妖呢?这是一只准确知道宇宙中所有原子的位置和动量,并能熟练使用牛顿定律的小妖,其可以通过力学定律精确地推演历史,并预测未来。
读到这里,相信同学们已经能够猜地八九不离十了:假如有这样一个足球游戏,其能够真实地还原每场比赛中的所有物理组成,包括场地、足球以及双方球员的身体状况、心态决策等等,那么我们就成为了这场比赛的“拉普拉斯妖”,并可以通过模拟这场比赛来对真实的比赛结果给出准确的预测。
脑洞开的再大一点,我们甚至可以为比赛双方都设置一个可以“进化”的 AI,并让他们之间不断对战,通过电脑自己的“左右互搏”而自我进化,从而筛选出一套最强的足球战术,从而反过来在现实中帮助球队所向披靡。
且不论上述黑魔法是否真的能实现,但不可否认的是,现在的足球游戏真的是做的很逼真,不论是各种诡异的足球弹道到人物的表情服饰,都在游戏光影的渲染下与现实无异。然而,不知道同学们有没有想过,电脑中的游戏为什么能如此栩栩如生地再现足球比赛,并且让玩家可以感受到球员真实的技术动作以及反应呢?下面,就让小编带领大家走进作为足球游戏支撑的,背后的物理引擎世界吧~🧐
实况、FIFA,然后物理引擎
当年小编玩的实况八,大致是这样一种观感:
可见,其人物造型仍有点“生疏”,而背后的草地也更像是一块简单的劣质贴图🤣。再来看看近几年(以 FIFA22 为例)的游戏场景:
是不是既真实又炫酷呢?现在游戏之所以能够带来如此真实的体验,离不开其背后的游戏引擎的支撑。
FIFA22 中使用的游戏引擎是大名鼎鼎的寒霜引擎:
而寒霜引擎中,作为其最基本物理部分引擎的,是 Havok 物理引擎 [1]:
其支持许多对于现实生活中物理现象的模拟,并通过不断的技术迭代,使得人物的动作更加真实。
而其更是被应用到了很多的 3A 大作中,例如:
而游戏引擎,顾名思义,犹如一款游戏的发动机,是一个游戏的核心部件。游戏中例如足球的滚动、球员们的对抗与碰撞,都是基于其主管物理的部分:物理引擎而实现的。而在物理引擎的底层,其也蕴含着十足的硬核物理原理。同学们不妨跟着小编一起看下去,去踢一场“最硬核”的世界杯吧!😎
物理引擎:刚体动力学、碰撞检测与约束
一个成熟的物理引擎,其核心主要包括以下三大部分 [2]:
1.刚体动力学部分
2.碰撞检测部分
3.约束部分
通过以上三个流程,物理引擎可以用如下图所示的一个循环来迭代计算每个物体的位置和速度信息,当迭代速度足够快且迭代结果足够精确时,显示到屏幕上的物体运动就可以称得上“栩栩如生”了。
物理引擎中的核心循环,通过一系列符合物理法则的迭代计算更新物体的信息,从而使得游戏世界栩栩如生
下面,让小编逐一为大家进行介绍。
刚体动力学
首先,要让计算机知道在游戏场景中,哪个地方存在一个什么样的物体,它是如何运动的,我们需要找到一种合适的方式来对于物体的形状、位置、速度等进行描述。在建模过程中,一个复杂的物体经常可以视为许许多多相对简单的刚体的组合,作为 building blocks, 我们首先考察刚体动力学。
刚体 (rigid body),被定义为形变为 0 的物体,其上任意两点之间的距离,无论刚体如何运动,都是不变的 [3]。在中学物理中,相信同学们都学习过质点的运动学,其由牛顿三定律描述 [4]:
牛顿三定律
从质点运动学给我们的启发,在研究刚体运动学时,我们也尝试借鉴描述质点时的成功经验,并在其上进行进一步扩充,以便正确描述一个有形状有体积的刚体。鉴于刚体有着以一个整体运动的特征,我们可以首先定义其质心:
质心
其中,求和对应于刚体质量离散分布,而积分对应连续质量分布的刚体。
顾名思义,质心就是刚体质量的中心,凡是与刚体平动有关的动力学性质,都可以用质心来代替。而质心也有很多有趣的性质,例如下图,如果一只玩具鸟的质心正好被设计在嘴部,则人可以用一只手指将其托起而不至翻倒。
但与此同时,由于刚体可以视为一系列质点的集合,其在空间存在一定的分布,所以如果仅仅使用质心来描述其动力学特性是不够的,我们还要研究刚体的转动。
为了研究刚体的转动,首先明确以下约定和记号 [6]:如下图,假设 XYZ 是我们进行观察的实验室坐标系(固定坐标系),而 x1x2x3 为固定在刚体上并随之一起平动、转动的坐标系(称之为动坐标系),图中一些约定如下:
约定与记号
则刚体的任何一个无穷小位移:
可以表示为一个随着其质心的无穷小平动
以及一个绕着动坐标系原点的无穷小转动
之和:
刚体无穷小位移
这样,刚体上任意一点的位置就可以被我们方便地描述了。下面,对上式逐项进行求导,来考察刚体上各点的速度:
其分别为刚体上某一点对于固定坐标系的速度,刚体质心的平动速度以及刚体的转动角速度。由此可见,刚体上任意一点的速度可以用刚体平动速度和转动角速度来分解:
下面研究刚体的受力与运动方程:首先,处理平动部分,并假设刚体的总质量为
则有
进一步,则有刚体平动的运动方程:
刚体平动的运动方程
这与质点的运动方程是一致的,而这个结果也再次验证了上文所说的,通过使用质心来描述刚体平动的合理性。
为了描述转动的运动方程,首先定义刚体的转动惯量张量:
转动惯量张量
上式对应于离散情况,对连续质量分布情况,只需要将各个分量用如下积分代替:
进而,可以定义刚体的内禀角动量
不妨选择惯性参考系使得刚体质心速度在该参考系中为 0(这一点总可以做到),并定义刚体的总力矩
则有刚体转动部分的运动方程:
刚体转动的运动方程
碰撞检测
现在我们已经知道如何描述一个刚体的位置以及运动了,但游戏场景中通常存在许许多多的物体,根据平时物理世界的直觉,如果两个物体相向而行,则其必定会在某个时刻相撞而弹开。在物理引擎中,专门有碰撞检测的算法来处理这一问题。
一般,对于物体的碰撞检测分为两个阶段进行,第一部分是较为粗糙的 Broad-Phase 部分,而第二部分是较为细致的 Narrow-Phase 部分。首先,看 Broad-Phase 检测 [7]:
在 Broad-Phase 检测中,就是先粗略地估计两个物体有没有可能相撞,来为之后的 Narrow-Phase 检测减少工作量。首先,定义物体的 Bounding Volume[8]: 能完全包住该物体的最小长方体的体积。
最常用的 Bounding Volume 方法有 AABB(axis-aligned bounding boxes), OBB(oriented bounding boxes), 和 Bounding Circle/Sphere,其示意分别如下图所示:
其中最常用,也是最节省计算资源的是第一种,为 AABB,在这一种 Bounding 方式下,判断两个物体是否可能发生碰撞,只需要检测包围住这两个物体的长方体有没有可能发生碰撞,从而将不规则物体碰撞的预检测化为了规则的长方体之间重合的检测。
在检测是否有碰撞发生时,通常采用 Sweep and Prune 方法 [9],其大意如下:在 AABB 方法下,在每个坐标轴上将每个物体所占有的长度的两端标记为 (b,e),如下图,以 x 轴为例:
分别在坐标轴上标记了三个物体在 AABB 方法下的边界,并产生了三个 (b,e) 对:
如此,对于任意两个物体 i 和 j,如果判定下列不等式之一成立:
即判定这两个物体有可能(即将或者已经在)发生碰撞。
例如上面横着的葡萄和足球,就满足
这个不等式,而从图中也可以看出,在 x 轴上,这两个物体的投影也确实是有重合的。
在进行完 Broad-Phase 检测后,我们就挑选出了所有可能存在碰撞情况的物体对,并只需要对于这些物体对进行更为细致的 Narrow-Phase 检测,其简介如下:
首先,考察一个物体的凹凸性,由于凸多面体有着更为方便的碰撞检测特点,所以我们期望更多地使用凸多面体去近似实际的物理物体。
凸多面体可以被定义为,一个几何体内任意两点所连线段都落在该几何体内的多面体。而凹多面体则反之,存在一条几何体两点连线,其不能完全包含在该几何体内。
可见,凸多面体存在着相较于凹多面体规则地多的形状,这也是为什么凸多面体在实际计算中更好判断是否发生碰撞的部分原因。但幸运的是,通过 Quickhull 算法 [10],我们可以方便地生成任意一个凹多面体的凸多面体逼近:
现在我们面对的问题就简化成了如何细致判断两个凸多面体是否发生碰撞。一种直观的想法是逐点判断两个物体的轮廓,是否有存在一个多边形的某个点被另一个多边形的所有边界点所包围。但在实际物理引擎中,通常使用更为优化的计算方法,以平衡计算开支。其中一种较为方便的方法称为 Separating Axis Theorem(SAT),其基本原理是 [11]:对于两个凸多面体,其不相交的条件是存在一条直线,使得两者在该直线上的投影不相交。
例如,上图六边形与梯形,存在一条投影轴 (Axis) 使得两者在其上的投影不相交,则判定这两个物体没有发生碰撞,这也与直接的直观认知是一致的。
现在我们知道了如何判定两个物体有没有碰撞,那么,假如两个物体发生了碰撞,其碰撞之后的情况又是什么样的呢?下面以质点碰撞为例,说明物理引擎对于碰撞的处理。
碰撞可以分为弹性碰撞与非弹性碰撞(包含完全非弹性碰撞和部分弹性碰撞),首先,看弹性碰撞,对于两个理想球体发生弹性碰撞,其过程中动量和能量都守恒,设其质量分别为 m1 和 m2,初始速度分别为 u1 和 u2,碰撞后速度为 v1 和 v2,则有 [12]:
对于非弹性碰撞,定义恢复系数
恢复系数
则有碰撞后速度:
可以看出,恢复系数为 0 对应完全非弹性碰撞,而其为 1 对应为完全弹性碰撞。恢复系数通常与两个碰撞物体的材质以及物理特性有关,是一个经验的参数,需要对两两物体间分别设定。
看到这里,两个物体在物理引擎中是如何判定是否发生碰撞的,以及如果其发生了碰撞后如何继续演化就被我们以至少一种可行的方式弄清楚了。但仅仅知道上述内容还不足以完成一个完整的物理引擎,这是因为在实际的物理世界中,处处都存在着约束条件 [15],例如一个小物块从斜坡上滑下,其在运动过程中必须保持自身处于斜面之上,而不能突然穿入斜面或者飞到天上去。
下面就让我们一起来看看,物理引擎中所用到的约束吧。
约束
从上文的讨论可知,约束通常意味着真实的物理情形对于物体位置和速度的限制,使之不会出现反常、反直觉的现象(例如游戏中偶尔出现的穿模 bug,就是约束没算好🤣)
那么,在物理引擎中,约束是如何进行计算的呢?下面用一个简单的例子进行说明:
例如,对于一个在碗里的小球,我们把小球从碗的边缘释放,使之在碗中自由运动。
把碗的内壁简化为一个半球面,并不妨设其半径为 R,并把小球简化成质点的话,则不难得到如下的约束:
其含义是小球到上图坐标系原点 O 的距离始终是碗的半径,也就对应着小球被约束在碗壁上这一物理实在。
下面,将上述约束写为更形式化的形式:
其中,C (r) 被称为约束方程,其等价于上面的约束条件。将该约束方程与最开始部分的运动学方程联立,即得到了对于物体的准确描述。而在物理引擎求解约束这一部分,则相应的需要对在计算过程中出现的违反约束的位形进行修正,通常采用人为引入一个约束力的方式进行,以保证最后不出现不合常理的游戏情形。(妈妈再也不用担心我的穿模啦😗)
最后...
相信通过上文的学习,同学们一定已经对物理引擎有了一个较为基础的了解了🤔,不过当然,就像鸟儿飞翔不需要懂空气动力学一样,同学们不必知道游戏引擎的每一个原理也可以畅玩游戏,但作为当今世界传播最广的娱乐方式之一,游戏,其核心:游戏引擎,尤其是物理引擎,却大量应用了最基本的物理原理。正是由于物理定律对于真实世界的精确描述,人们才得以在计算机构建的世界中搭建一个栩栩如生的舞台,在其上有列国纷争、异世冒险、激情赛道、鹰击长空、实况足球等等等等,但小编也希望同学们在看完这篇科普后,也能在以后再次打开实况八的时候,或多或少地想到,作为游戏核心支撑的物理定律,其强大的威力以及其无尽的魅力。而至于开头说的拉普拉斯妖式预测可能还有很长的路要走,但左右互搏术的思想已经被用于多种情景中,例如大名鼎鼎的 Alpha Go Zero。
最后,希望同学们既能够享受游戏,也能够享受本届世界杯的无穷魅力,就像 1998 年法国世界杯主题曲所唱一样,"Here we go, 啊嘞啊嘞啊嘞,GOGOGO,啊嘞啊嘞啊嘞 "👻
参考资料:
向上滑动阅览
[1]: 寒霜引擎_百度百科 (baidu.com)
[2]: Video Game Physics Tutorial | Toptal
[3]: Rigid body - Wikipedia
[4]: 牛顿运动定律(物理定律)_百度百科 (baidu.com)
[5]: Center of mass - Wikipedia
[6]: 朗道理论物理教程 (卷 01),《力学》(第 5 版),[俄] 朗道、栗弗席兹,李俊峰、鞠国兴 (译),高等教育出版社,2007
[7]:Chapter 32. Broad-Phase Collision Detection with CUDA | NVIDIA Developer
[8]: Bounding volume - Wikipedia
[9]: Sweep and prune - Wikipedia
[10]: Quickhull - Wikipedia
[11]: Hyperplane separation theorem - Wikipedia
[12]:Elastic collision - Wikipedia
[13]: Coefficient of restitution - Wikipedia
[14]: Inelastic collision - Wikipedia
[15]: Constraint (classical mechanics) - Wikipedia
本文来自微信公众号:中科院物理所 (ID:cas-iop),作者:Callo
广告声明:文内含有的对外跳转链接(包括不限于超链接、二维码、口令等形式),用于传递更多信息,节省甄选时间,结果仅供参考,IT之家所有文章均包含本声明。