移动端布料的模拟 -基于DynamicBone的实现

布料的现状:

衣服的长裙可以说是现代布料模拟的难点表现,一般的衣服会好一些(市场上有做的不太好的做法,就是为了衣服居然添加不少约束来限制人的运动)看了一下现在的基本上都是飘飘然的感觉是有,但是要能容忍一定程度的穿模,就比如天刀衣服也会穿模天刀穿模,毕竟在国内已经算很好的游戏了,做的布料效果还贼多。
衣服摆动实现方式有两种:模型骨骼动画,物理计算;骨骼动画就是通过Max或者Maya对衣服布料进行骨骼绑定,这种方式实现的布料不自然而且摆动样式固定。另一种实现方式是对布料进行蒙皮但是不绑定骨骼动作,只是作为物理计算的关键点。

布料的模拟:

1、基于动画的衣料模拟 — Animation bone
把衣服当身体一样进行动画处理,在衣服上设置joint和骨骼,并进行相应的插值处理。优点在于便宜和可控(移动端),缺点在于不够真实、和环境没有交互以及设计上受限

2、基于刚体的衣料模拟 — kinematic bone
像布娃娃系统一样设置一些骨骼joint,利用物理系统去进行计算处理。优点在于便宜和可交互,缺点在于质量不可控、动画师的工作量大、不鲁棒以及需要高质量物理系统参与3、基于mesh的衣料模拟简单讲就是获得物体的mesh,并对每一个顶点进行计算处理。而由于物理系统计算的昂贵,所以一般不会像渲染时一样对每个顶点计算,而是相对稀疏。(少几倍到十倍)

具体做法上细节如下(以人物身上的衣料为例(披风)):

首先,对每一个顶点要设置最大的移动半径。一般来说,对离人物越近的顶点,最大移动半径越小(比如脖子处基本不动),一方面更符合物理实际,另一方面可以减少穿模概率

在游戏开发者角度来说,需要设置衣料的物理属性。以UE4为例,有如下属性:

现在最常用的是处理弹簧算法的方法是:Position Based Dynamics(PBD),其简单思想是用拉格朗日力学替代传统力学那一套,放弃“约束 - 力 - 速度 - 位置”的逻辑而把所有的力学关系描述成一套约束,并直接解出最后的位置,而不关心速度。
在这里插入图片描述

基于动态骨骼的布料模拟:

有三种对布料的仿真,一种是物理骨骼,一种是物理骨骼的布料,一种是最好效果的布料。对于移动端unity magica cloth 说是性能更优。

长裙说是现在都难的,一般的衣服会好一些,(市场上有做的不太好的做法,就是为了衣服居然添加不少约束来限制人的运动)看了一下现在的基本上都是飘飘然的感觉是有,但是要能容忍一定程度的穿模。
市面上特别是游戏移动端衣服大部分都是unity的几个插件比如DynamicBone,UnityChanModel包里面的【SpringBone】[2],以及搭载了“JobSystem”与BurstCompile”的强大插件【MagicaCloth】,要想高效快速的实现动态骨骼的话,推荐基于MagicaCloth。 动态骨骼,spring bone,dynamic bone以及magic cloth都支持,而且算法都几乎一样的,随便哪个效果都还行, 但是magic cloth解决了其他两种动态骨骼不能解决的问题,那就是对于一束动态骨骼,它还可以进行横向约束。

DynamicBone参数含义:

DynamicBone的原理动态骨骼Dynamic Bone算法详解解释的很清楚我就不再重复~
然后我要整理与谈的是算法的优缺点及其参数的含义。
动态骨骼的基本属性四个属性的取值范围都是[0, 1],

Damping 阻尼:阻止简谐运动的惯性运动,相当于弹簧的摩擦力。为0时简谐运动过程不会主动停止,为1时简谐运动过程不会发生; 值越小,表现的越轻;值越大,越重。比如:头发稍重,布料稍轻。
Elasticity 弹性:决定回振移动强度,在简谐运动过程中作为额外的作用力将节点拉到还原位置,相当于弹簧的弹力。为0时系统形变不会主动还原,为1时形变不会发生; 伸缩:值越小,越容易弹飞;值越大越像弹簧。比如:前摆弹性太小时,摆动幅度会摆到身后。弹性参数是最难把握的,需要配合阻尼参数一起调整效果。
Stiffness 刚性:限制最大振动幅度与方向,保证碰撞处理前节点不会跑到指定范围外,相当于弹簧的硬度。为0时不发挥作用,0到1时限制范围从2倍原始距离到0线性衰减;
值越小,越柔软;值越大越硬。目前使用的头发和布料都属于比较柔软的,参数设置到0.1基本上没有太大问题。
Inert 惯性:限制形变幅度,在每一帧的简谐运动迭代发生前,无条件随物体整体运动拉动节点,拉动距离为Inert * 整体运动距离; 值越大,惯性越小。参数一般设置在0.5以上,避免动作幅度较大时,摆动过大。

除此之外还有其他常用的关键属性:

强制力:在DynamicBone节点上施加的额外力,方向是在全局坐标系中的,注意Force与Gravity不同,是无条件生效的,会一直把节点向指定方向拉动;
半径:指定DynamicBone每个节点与碰撞体发生碰撞的半径,注意节点互相之间不存在碰撞关系,注意这个半径是0碰撞依然会生效;
Freeze Axis 固定轴:值有{none,x,y,z}非None的情况下,所有节点在局部坐标系的对应的轴上在值不会发生变化;
Gravity 重力:在DynamicBone节点上施加的重力,方向是在全局坐标系中的,注意DynamicBone的重力比较特殊,只在节点运动发生时起效,会在节点运动时把节点向重力方向拉动;

DynamicBone碰撞

DynamicBone提供了简单的碰撞功能,允许使用者禁止进入或者离开某些特定的区域,组件提供了球型和胶囊体两种区域的碰撞体,允许使用者Outside或者Inside的区域。
碰撞功能的使用非常简单,只需要在骨骼可能会发生碰撞交互的Node上添加DynamicBoneCollider组件,并且设置以下属性即可。

方向:胶囊体在当前node局部坐标的方向,区域是球体的时候无效;
碰撞体中心:指定区域中心与node位置的偏移量;
碰撞体半径:碰撞半径区域内球形部分的半径;
区域高度:,这个值在小于2倍Radius时无效,会使区域变成球型,高于2倍Radius时生效,区域会变成胶囊体(可视化模型是两个球体);
区域边界:Outside表示区域会作为碰撞盒与DynamicBone节点发生碰撞,阻止节点进入区域内,而Inside则会约束节点在区域内,阻止节点离开区域;
然后需要将DynamicBoneCollider对象添加至与其发生碰撞交互的DynamicBone组件的Colliders属性中。

限制与缺陷

性能的消耗:在这里插入图片描述
我们假设场景里面有30个角色模型,每个模型有10条骨骼链,每条骨骼链有10根骨骼,那一共有3000根骨骼。剑网三的数据 小米Max2在组成动态骨骼中的CPU消耗,占整个CPU消耗大概10%,这是一个非常大的开销。

动态骨骼的层级越深所消耗的性能越大。所以就引发了在dynamicbone基础上改进的各大插件。

DynamicBone主要是消耗CPU的性能,为什么这么消耗的原因是它的运算很复杂,需要做大量的模拟运算。这里值得一提的是,在整个模拟运算的过程中,需要对每根骨骼进行世界坐标、世界旋转、世界矩阵等世界变化的获取和设置等操作。骨骼数量 = 模型每个模型的骨骼链数链的骨骼个数,骨骼的数量越多消耗越大,同样的相同骨骼下动态骨骼层级越深越消耗性能,层级越深在计算世界坐标、旋转的过程中开销是非常大的。层级越深,消耗就会越大。

DynamicBone限制与缺陷

  1. 由于DynamicBone完全不发生拉伸和压缩的特性,DynamicBone并不适合模拟凝胶、橡胶等各方向形变明显的物体,而更适合模拟头发、绳子等不容易拉伸但容易形变的物体,
    衣物则要看衣物材质是否非常容易拉伸。
  2. 虽然有简单的碰撞机制,DynamicBone的各节点之间是不存在碰撞的(当然可以通过在各节点都设置碰撞体组件来实现,但因为开销会很高所以不建议!就比如衣服布料的自碰撞不建议使用),这意味着DynamicBone
    模拟的物体在刚性为0的时候可能会发生自我穿插;
  3. 另外一方面DynamicBone所有计算都不考虑时间因素,所以同样弹簧参数不同更新频率参数下表现会非常不同,加大了调参难度。

关于碰撞及其交互:

什么是碰撞体:
碰撞体本身就是一个Node节点,对于虚拟衣服来说就是身体添加一些空的骨骼节点Joint作为辅助的碰撞体。碰撞体的形状是根据碰撞体半径与区域高度来决定:高度小于两倍的半径为球体,反之则为胶囊体。

碰撞的穿模:

使用动态骨骼的碰撞会不可避免的出现穿模现象!比如很热款的手游在国内已经算很好的游戏,做的布料效果还非常多【关于天刀衣服穿模的问题。——百度贴吧】https://mbd.baidu.com/ma/s/mRfibSBJ。即使之前说过的效果不错的magica cloth也有这个问题,magica cloth那个作者也有做防穿模,靠一个碰撞体的平均浸透距离,总之可以做到大幅度动作穿插少,但是服装无法贴身!碰撞检测这块,DynamicBone基础算法也是只用粒子和碰撞体碰撞再加粒子间约束。我个人觉得没有线面这种基元,只靠粒子碰撞和形态约束,剧烈运动该穿要穿的,所以这里主要体现的是碰撞交互的过程,想要真的解决穿模还是布料模拟靠谱。

碰撞交互:

比如在衣服的裙子碰撞体就可以如图
在这里插入图片描述

红色是身体的骨骼Joint,其中黄色的是辅助的碰撞体,可以根据需求适量添加碰撞体,躯干加一排球型的碰撞体可以会更好模拟,或者直接一个胶囊体。碰撞的交互除了跟碰撞体的属性有关外还跟动态骨骼的属性:半径密切相关!
在这里插入图片描述

如图是一件裙子,其中红色的球是动态骨骼的根结点,其余的绿色就是各个子骨骼节点,或者称之为粒子。粒子的形状只有球状,通常粒子半径较小比如0.5用来模拟绳子等等的类弹簧质子系统(所以一般不建议直接调粒子半径,因为粒子半径通常药维持较小);蓝色的是碰撞体,碰撞就是蓝色的碰撞体与红色或者绿色的粒子碰撞,又或者是碰撞体球与各个粒子球之间的根据R+r的半径来碰撞。除此之外还与方向、碰撞体中心、区域高度、区域边界。

如下图是游戏中动态骨骼的碰撞体做的方案
在这里插入图片描述

unity的几大动态骨骼插件:

1、unity bone cloth spring system,base by jobs:
Automatic-DynamicBone

对应源代码:Automatic-DynamicBone源代码

在这里插入图片描述

2、SPCRJointDynamic
SPCRJointDynamic

参考资料:

DynamicBone(动态骨骼)源码赏析
动态骨骼Dynamic Bone算法详解
DynamicBone的使用

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值