赞
踩
约束在物理引擎中非常重要,就像shader是实现各种渲染效果的核心,约束(Constraints)是物理引擎中的核心概念.
在一些譬如机器人运动的真实世界中的物理约束求解,都是非常复杂且耗时的.在游戏中,由于帧率的要求,我们没有足够的时间来得到绝对正确的结果,我们的目标是一种精度尚可,比较稳定的求解方式.
设想一个在坡道上滑板运动的人,滑板被限制在坡道上,这样的约束叫做位置约束(position constraints).
用
很容易算出
来看下物理引擎中无处不在的接触约束(contact constraint).比如一个在固定平面上放着的盒子,我们针对盒子的左下角的P点来进行求解.接触约束的约束条件是:两个物体的接触点不会沿着接触的法线方向移动.这样我们很容易得到位置约束
只有位置约束是不够的,我们将
因为我们假设地面是固定的,所以有
对于盒子
为了使速度约束得到满足,我们使用一个求解器(solver)对约束进行求解.求解的方式,就是沿着接触法线的方向,在
接下来我们的任务就是求解
用牛顿力学分析冲量作用前后的速度和角速度:
根据速度约束得到:
得到:
带入一下,得到:
这样根据上面的式子,就可以求出
为了简化计算,再次对式子进行整理,得到:
根据上面的方式,我们成功对单个约束进行求解.下面问题是,如何对多个约束进行求解?
同时对多个约束进行求解是一件相当困难得工作,在一个约束上得冲量会影响到其他的约束.如果我们把所有的约束放到一起用全局求解器进行求解,就需要构造一个求解的矩阵.比如现在有100个约束,就要构造100x100的矩阵进行求解,对于大部分游戏来说,这个耗时是无法接受的.
在游戏中更多地还是用本地求解器来进行约束求解,使用多次迭代的方式求解,这样只需要线性的时间和空间消耗.
我们使用一种叫做连续冲量(Sequential Impulses)的方式进行本地求解,基本过程大致是这样的:
假设现在有一堆堆叠在一起的圆形小球,我们来计算接触约束对小球产生的冲量.在开始求解之前,先给每个小球施加一个重力.
我们按照任意的顺序来对接触冲量进行求解,第一次迭代后,距离目标还差很多.因此这里再迭代两次,发现还是有一定的误差,这样就会导致求解后计算运动时两个小球重叠在一起.
我们可以把收敛堪看成一个逐渐累乘减少误差的过程,每次求解器迭代剩余的误差比例为
如果只有一个小球放在固定平面上,那只需要一次求解就可以收敛到正确的结果.
两个相同质量的小球堆叠,需要5次迭代达到95%收敛.
一个轻点的小球放在重的小球上(1:2),只需要3次迭代就能达到95%收敛.
一个重的小球放在轻的小球上(2:1),需要更多的次数达到收敛.
如果上下小球的重量比例是10:1,则需要大概50次迭代才能达到95%收敛.
因为在计算下面小球的接触冲量时,是不知道上面小球的存在的,因此上下的小球质量比例越大,需要的迭代次数也越多.
考虑另外一种情况,就是多个小球堆叠在一起,也会使需要的迭代次数变多.
为了解决迭代次数过多的问题,我们可以使用暖启动(warm starting)的方式来减少迭代次数.因为大部分情况下我们的帧之间是有连贯性的,我们可以利用连续的数帧来平摊计算的迭代次数.
实现的原理非常简单,在一帧计算出累积冲量值后保存起来,在下一帧开始计算之前,从上一帧保存的值开始计算.
当然这样做也是有一定的副作用的,如果负载出现突变,可能会导致没有足够的时间使结果收敛.
像接触约束这样的约束,对求出来的
需要注意的是,这里的
比如一个放在地面的盒子,有两端两个接触点,需要分别求解.
如果是两个堆叠的盒子,而且上面和下面的质量比值较大,就会出现过冲的情况.
除了位置约束和速度约束,如果再进一步可以得到加速度约束.速度约束是通过冲量实现的,加速度约束通过调整物体的受力来实现.
但是对于接触约束,两个物体的碰撞时,互相之间的力变化是很快的,而且有一个很大的峰值,所以加速度约束不能适用于接触约束.
对于其他类型的约束,加速度约束同样还有一些问题,比如一个摩檫力约束,循环求解时可能导致一个无穷大的值.如果使用速度约束求解就不会出现这种问题.所以我们一般不会用加速度约束进行求解.
速度约束看起来是进行刚体约束模拟的最佳方案,大部分类型的约束都可以使用速度约束实现,像摩檫力约束甚至只会影响物体的速度.
但是只有速度约束是不够的,因为物体的旋转是非线性的,再加上我们上面提到收敛误差.连续冲量的方式求得的值是有误差的,而连续冲量本身不关心这个误差,所以我们需要位置约束对误差进一步校正.
比如在接触约束中,再位置约束求解中,通过对求得的冲量加上一点虚拟冲量,来使结果满足位置约束.当然这里的虚拟冲量,只在这一帧中有效.
https://box2d.org/files/ErinCatto_UnderstandingConstraints_GDC2014.pdf
https://www.toptal.com/game/video-game-physics-part-iii-constrained-rigid-body-simulation
我在学习物理引擎的时候,发现很少有这方面的文章,所以用这个系列文章记录下.文章是基于这个系列教程的翻译https://www.toptal.com/game/video-game-physics-part-i-an-introduction-to-rigid-body-dynamics,再加上一些自己的理解和补充. 个人感觉游戏物理引擎,这些年基本没太大变化.文章中所讲到的技术,也大都是十几年前的东西.
希望深入学习的朋友,推荐阅读https://box2d.org/publications/系列的文章,是Box2D作者在历年GDC大会上的演讲内容.
目前学术研究上的物理引擎,主要是基于真实物理的动画仿真,也是Siggraph的热点.当然其中用到的技术点和本系列文章中的技术点大相径庭,而且这些东西目前很少用到游戏当中.知乎上也有很多介绍这方面内容的文章,这里就不再赘述.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。