移动端布料的模拟 -基于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属性中。

DynamicBone限制与缺陷

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

unity的几大动态骨骼插件:

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

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

在这里插入图片描述

2、SPCRJointDynamic
SPCRJointDynamic

参考资料:

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

猜你喜欢

转载自blog.csdn.net/chenweiyu11962/article/details/127625716