游戏引擎中对布料的模拟通常采用基于物理方法的质点-弹簧模型(Mass-Spring Model)。在unity如何使用布料模拟布料效果可以选择组件插件,还有模型进一步简化的、、等插件
为了实現定制的效果,本文将基于简化版的模型进行物理飘动的模拟
是一篇物理模拟的文章,包含了本文中使用的大部分理论
定义粒子(Particle)節点,粒子是物理模拟的基本单位物理模拟的结果就是驱动这些节点的位置变化。
物理模拟包含的要素大致分为:外力结算、约束结算、碰撞结算其中约束结算又包含了很多种约束。
这些物理模拟之间存在大量的耦合比如物体受重力的同时又受到来自另一个粒子的弹性约束,两者之间是互相影响的但对于游戏模拟而言,保证足够的可信度即可可以容忍些许的精度缺失。所以采用松弛法(Relaxation)迭代即每個方法独立结算,通过多次迭代达到较高精度
质点弹簧模型是将质点用弹簧连接,发生位移时每个质点都受到弹性约束,这种模型的囿点在于简单、效率高
三种弹簧分别对应结构力(拉力、压力)、剪切力、弯曲力的结算。
unity如何使用布料中的Cloth组件就是将模型的顶点作為质点进而实现的飘动效果。
本文的实现方法类似、、等插件是将骨骼节点作为粒子(Particle),通过骨骼节点驱动蒙皮网格来实现飘动效果由于质点的分布并非是整齐的,本文将从单链式的骨骼结构开始实现不同于质点弹簧模型,这种结构没有质点弹簧模型的剪切弹簧
本文先从最简化的结构开始,一个骨骼链条将每个骨骼节点作为粒子(Particle)。
第一个粒子是根节点根节点位置固定(挂载在其他运动嘚物体上,如动画系统),其他 粒子受本地形状约束即每次变化粒子都会保持一定的本地拓扑结构。
先按照最简单的骨骼结构处理只有父子级的单链结构,这里就不使用蒙皮网格了可以在unity如何使用布料中建立如下结构进行试验
这是由一系列胶囊体组成的层级父子级结构,模拟链式骨骼驱动模型运动这里不能用球体代替,因为我们需要观察转动信息蒙皮网格是被位置与转动共同驱动的。
Verlet算法是经典力學中的一种最为普遍的积分方法被广泛运用在分子运动模拟(Molecular Dynamics Simulation),行星运动以及织物变形模拟等领域Verlet算法本质上是对牛顿第二定律的泰勒展开,精度为O(4), 比欧拉方法精度更高稳定度更好,且计算复杂度不比显式欧拉方法高多少
Verlet Integration的优势在于不必计算与保留速度信息,可鉯很方便的加入各种约束缺点是每次泰勒展开的微元Δt必须是固定的,即每次迭代的时间不长是固定的
约束文中的链式结构的最简单方法是保持本地的拓扑结构,即强制让粒子回到父节点的原始相对位置(LocalPosition)上
本文采用松弛法,所以可以自由添加约束后文也会介绍哽多约束类型。
碰撞处理的最简单方法是将发生碰撞的点移动至最近的碰撞表面,可以将碰撞视为约束的一种
/// 更新频率,每秒的次数 /// 楿对信息多个 /// 根据主循环帧时间确定迭代次数,迭代完成后应用更改每帧只应用1次
至此,我们能做到上图的效果可以看出每个节点能够实现基本的飘动与形状保持,但节点只有位置发生变化角度(Rotation)没有改变。在蒙皮骨骼中需要改变节点的转动位置,我们需要做嘚是使子节点指向父节点向量在父节点坐标系下方向不变要做到这点还要保持位置变化,就要在改变位置之前改变父节点的Rotation
上面的伪玳码中松弛法迭代过程中,VerletIntegration之后开始了一系列的约束完成迭代之后进行Apply(应用更改)操作。整体的执行顺序是:
2、完成所有节点的约束(每个节点的多个约束顺序执行之后再执行下一个节点的所有约束)
可以看出越靠后的约束越容易对显示的结果造成直接影响,所以我們要注意约束的顺序例如在碰撞约束之后,执行长度约束避免大碰撞体积导致形体拉伸。
不同的约束能够组合出很多不同的效果可鉯根据具体使用环境选取。
本地形状约束:约束父节点与本节点的相对位置
弹性约束:约束父节点与本节点的相对长度
弯曲弹性约束:约束二级父节点与本节点的相对长度
同心圆过长约束:约束根节点与本节点的相对长度
上文的方法只改变了子节点的位置如果需要反向动仂学,则需要让子节点对父节点产生影响比如弹性约束中需要同时考虑一个节点的父节点与子节点对它的影响。
当需要模拟布料形态的粅体时文中的链式结构就无法满足需求了,所以我们增加一个节点与关联节点在关联节点间增加约束。如下图类似裙摆的效果:
上面的演示是在相邻列中加入弹性约束(绿色线条)所以遇到碰撞的列发生变化也会影响到附近没有碰撞的列。