参考
Unity手游开发札记——布料系统原理浅析和在Unity手游中的应用,转载了部分内容。
一、什么是布料系统
随着时代的发展和移动设备硬件性能的提升,物理引擎被越来越多的移动游戏所使用。物理引擎处理的对象主要可以分为刚体(Rigid Bodies)和柔体(Soft Bodies)两大部分,刚体主要应用在物理碰撞、破碎、布娃娃等系统中,而柔体最为重要的应用代表就是布料系统。
在物理引擎中,通过物理计算来模拟布料效果的系统可以称之为布料系统。虽然名为布料系统,但并不仅仅用于表现角色衣服的布料效果,而且可以应用于毛发、坠饰,甚至女性的某些柔软部位……下面的几张图就给出了一些游戏中应用了布料效果的地方。
二、为什么要使用布料系统
在物理引擎被广泛使用之前,游戏中的绝大部分动态效果都是通过固定的动画来表现。这个做法非常容易理解——角色身上的飘带也好,头发也好,在动画师的眼中,与角色的手脚四肢没有任何区别,添加骨骼,进行蒙皮,制作动画,无论一帧一帧自己手K还是用Max的柔体效果插件生成,都可以制作出逼真的布料运行的效果。(在更早的使用网格动画的年代,原理也相差不多。)如果你觉得效果不够好?那简单,再多加一些控制骨骼,多给美术一些时间,就可以做出更好的效果。
基于动画的制作方法虽然可以满足大部分的需求,但随着时代的发展,无论玩家还是游戏开发者都在追求更好更真实的效果,这种制作方式表现出来的布料效果的缺点慢慢显现出来:
1. 布料效果不够真实
虽然在单个的动画中,布料的表现效果足够好,但是在各个动作之间转换,甚至多个动作融合到一起进行表现的时候,用于表现布料效果的骨骼融合结果就会不那么自然,真实感也就大打折扣。
2. 无法应对越来越多的变化
当角色有移动速度的变化时,我们通常可以通过改变动画的播放速度提供对应的表现,但是移动速度很快和移动速度很慢时,裙摆头发的飘扬效果都是完全一样的,甚至当玩家面对一堵墙按下移动按钮,角色开始播放跑步动画,虽然并没有移动,但仍然可以看到角色的裙摆和头发在迎风飘扬……
3. 限制时装的设计和制作
目前大部分游戏在设计角色的时候由于要考虑到角色未来可能会出的时装,可能采用最大化骨骼的制作方案。所谓最大化骨骼,就是在角色制作初期就确定好角色最多可能有哪些骨骼,在之后制作角色时装的时候,要完全在最初定义的最大化骨骼范围内。如果超出了这个范围,就需要修改所有时装的模型以及角色的所有动作,并全部重新导出,这种修改的代价是非常大的。
这些预留的最大化骨骼,有很多是在角色默认设计的时装中没有被使用的,但是为了给未来预留更多的可能,因此需要留好控制裙摆、长发等部件的各种最大化骨骼,而且注意,这些骨骼上都需要制作对应的动画效果,或者在未来制作某套需要这一骨骼的时装的时候,把所有的动画添加上对应骨骼的动作,重新导出。在美术工作量、美术资源的大小、游戏的运行效率等方面,这种做法都有一定的负面影响。
当然,大部分引擎都已经支持了子模型的方式,也就是引擎可以把一些子模型动态地合并到一套骨架上。但是《剑灵》的制作人员提供了另外一种思路——主角的动画只制作身体主要部位的动画效果,对于所有的裙摆、坠饰这样的物体,都统一使用布料系统来制作。这一制作方案可以完美解决设计角色时装时要考虑是否有骨骼可以驱动的问题,从而解放美术的想象力,节省美术的冗余工作,运行时的效率也得到一定的提升。
4. 无法支持动画重定向之后的动作
动画重定向是一种常用的动画复用技术,可以让一个模型A使用另外一个模型B的动画数据,但是如果模型A带有裙摆、长发这样的额外部分,而模型B的动画中并没有驱动对应网格的骨骼,那么重定向之后的裙摆就会非常僵硬
三、插件调研
需要提前说明的是,前文所描述的布料系统及其原理,主要是针对在主机和端游上使用的物理模型的布料效果,它们基于网格顶点,可以做到非常精细的效果。其实还有一种制作布料效果的方法——基于骨骼进行物理模拟。这种方法的原理更加简单,把骨骼当做一个个通过关节连接在一起的铰链,给予一定的物理参数,来模拟动画之外的动态效果,而最终效果是通过蒙皮反应到模型网格上的。由于骨骼数量通常都比顶点数量少很多,因此这种方法具有更高的运行效率,在手游中使用得也比较多,前面对于《王者荣耀》中妲己的辫子截图,笔者猜想就是使用的类似的方法。
沿着这两个不同的思路,笔者查看了几个相关的插件。
a. 基于骨骼的方案。基于骨骼的方案在Unity的AssetStore上有多个实现,原理都差不多:Dynamic Bone、Swing Bone、PhysicsBone
b. 基于质子-弹簧模型的方案。主要看了两个,一个是官方的Cloth Component,一个是Obi Cloth。
在质点-弹簧模型中,布料被当做网格上的粒子来进行模拟,这些粒子之间由弹簧减震器进行连接。每一个弹簧连接两个粒子,并且基于粒子的位置和速度来产生作用力。粒子可以受重力影响,弹簧可以设置为不同的类型,比如拉伸弹簧(stretch springs)、剪切弹簧(Shear Springs)和弯曲弹簧(bend springs)等。
1.Obi Cloth
效果可以参考 https://www.bilibili.com/video/BV1zX4y1w7Mg
2.Magica Cloth
《Unity Magica Cloth从入门到乳摇》之(1)基础设置
https://www.bilibili.com/video/BV1Ah411Q7MF/
https://www.bilibili.com/video/BV1Tz4y127Hp/
Magica Cloth 布料模拟使用心得,以及插件功能介绍(一)
Magica Cloth 布料模拟使用心得,以及插件功能介绍(二)
四、官方的Cloth
基本步骤包括:
- 在Mesh Renderer所在的GameObject上添加Cloth组件;
- 点击Edit Constraints按钮在弹出的Cloth Constraints界面中编辑Mesh顶点上的常量,比如最大距离、表面渗透。也可以通过笔刷来刷出渐变的值。
- 在Cloth组件中设置参数和碰撞来提升效果。
Cloth组件的效果因为是基于网格的,因此不需要绑定骨骼也可以做出动态的效果,而且飘动的单元是mesh顶点,因此效果也比较细腻。(我们的角色面数也比较省,当然做不到像端游那么精细的效果。)
参考https://docs.unity.cn/cn/2019.4/Manual/class-Cloth.html
布料 (Cloth) 组件与带蒙皮的网格渲染器 (Skinned Mesh Renderer) 协同工作,从而提供基于物理的面料模拟解决方案。此组件是专为角色服装设计的,仅对蒙皮网格有效。如果向非蒙皮网格中添加 Cloth 组件,则 Unity 会删除非蒙皮网格并添加蒙皮网格。
布料不响应场景中的任何碰撞体,也不会将力反射回世界。添加 Cloth 组件后,该组件完全不会响应和影响任何其他实体。因此在手动将碰撞体从世界添加到 Cloth 组件之前,布料和世界无法识别或看到彼此。即使执行了此操作,模拟仍是单向的:布料可以响应实体,但不会反向施力。
此外,只能对布料使用三种类型的碰撞体:球体、胶囊体以及使用两个球形碰撞体构造而成的圆锥胶囊碰撞体。之所以存在这么多限制是为了帮助提高性能。
Cloth只能必须和Skinned Mesh Renderer搭配使用, 但是这不代表使用简单的物体时还必须在Max中导出一个带有蒙皮信息的FBX, 其实可以新建一个GameObject然后赋予Cloth组件, 这会自动添加Skinned Mesh Renderer组件, 然后在Skinned Mesh Renderer组件中赋予基本体的Mesh上去并且设置正确的材质也完全可以。布料可以接受外部影响,但完全不会将影响赋予外部刚体, 换句话说, 布料系统的物理模拟是单向的。
参考Unity3D 布料系统 And Cloth Constraint 及 Mesh双面渲染
1.简单示例
效果如图,这块布固定在一个点上,受重力影响来回摇晃。
先创建一个Plane,然后添加Cloth组件。然后Edit cloth constraints:
现在能看到很多小黑点,随便选一个,勾上Max Distance,即可实现上述效果。
也可以使用鼠标左键拖动框选,或者SHIFT多选。如果把一条线上的黑点全部选中,勾上Max Distance,就是下面这个效果:
2.属性,这个可以参考官方文档
- Stretching Stiffness 布料的拉伸刚度。数值范围为0~1,值越大,越不容易拉伸。
- Bending Stiffness 布料的弯曲刚度。数值范围为0~1,值越大,越不容易弯曲。
- Use Tethers 施加约束以帮助防止移动的布料粒子离开固定粒子的距离太远。此属性有助于减少过度拉伸。
- Use Gravity 是否应该对布料施加重力
- Damping 运动阻尼系数。阻尼会应用于每个布料顶点. 要想打造看上去抖动更小或更大的布料, 可以设置这个属性。设置为1时,可以看到布料受重力影响,落下速度会慢很多。
- External Acceleration 施加在布料上的恒定外部加速度。
- Random Acceleration 施加在布料上的随机外部加速度。可以模拟风吹。
- World Velocity Scale(定义角色在世界空间的移动对布料顶点的影响):值越大,布料对角色在世界移动的反应越剧烈。这个参数基本是用于定义蒙皮布料的空气阻力。
- World Acceleration Scale(定义角色在世界空间的加速度对布料顶点的影响):值越大,布料对角色在世界空间的加速度反应越剧烈。如果布料看起来很生硬,那么可试着将该值增加。当布料在角色加速时表现的不稳定时,那么可试着将该值减少。
- Friction(摩擦系数):数值范围为0~1。当布料与其他对象碰撞时产生的摩擦力,只会影响到布料的模拟,并不会影响到刚体对象(单向模拟)。
- Collision Mass Scale:用来设置碰撞质量缩放。
- Use Continuous Collision 启用连续碰撞来提高碰撞稳定性。
- Use Virtual Particles 每个三角形添加一个虚拟粒子,从而提高碰撞稳定性。
- Solver Frequency 解算器每秒迭代次数。
- Sleep Threshold 布料的睡眠阈值。
3.Capsule Colliders Sphere Colliders
要对布料产生交互的ClothSphereColliderPairs,比如一个人物模型,或者小球。
可以理解为他是按照一组来的, 一组中可以只有一个SphereCollider, 也可以有两个, 当有两个的时候, 那么这两个SphereCollider会在布料的碰撞系统中被”焊接”起来. 这样就允许通过两个大小不同的SphereCollider来组合成一个圆锥形状的碰撞体了。
至于碰撞体放在Cloth自身、子物体、外部都可以,根据需求来。
4.上面示例中用的约束工具
Max Distance可以设置每个顶点最大可移动距离. 最常用的用法是将不能动的顶点的Max Distance设置为0
Surface Penetration控制的是顶点最大可以嵌入到Mesh里面的程度. 在布料网格顶点比较稀疏的情况下可以明显对比出差别
Visualization这里能够选择当前在Scene视图中预览Max Distance还是Surface Penetration. (这两者二选一), 还能选择是否让操作影响视口背面的顶点
5.使用 3 种不同的模式来编辑布料约束值
- Select 将固定约束值应用于预先选择的粒子组。
- Paint 通过用画笔绘制布料粒子来施加固定的约束值。
- Gradient 将约束值的从左到右线性渐变应用于预先选择的粒子组。
根据使用的模式,工具属性和所需执行的步骤会有所不同。在所有情况下,最后一步都对应于应用约束值的操作。
Select编辑模式要先通过框选, 或者Shift+点击来多选, 来选中顶点, 然后勾选Max Distance或者Surface Penetration前面的复选框, 代表我现在要改变选中的顶点的值了! 然后再在后面的数值里面输入想要的数值。
要想将当前有数值的顶点设置为Unconstrained, 只需要选中那些带有数值的顶点然后将对应复选框取消勾选即可。
6.色谱
根据当前在整块布料中应用的最小值和最大值,为上述选定的约束类型提供粒子颜色和约束值之间的对应关系。黑色始终表示粒子没有约束。
注:这里会在所有球中找最大值,作为色谱的最大值。然后其他球会根据最新的色谱,改变颜色。
7.Constraint Size
代表布料粒子的球体的显示大小。在方便时可以调整此值以便简化约束版本。这个属性对约束本身没有任何影响。
注意,这个值过大,会导致球全叠在一起,面板黑了,如图:
那些红色的斑点,实际上就是Max Distance=0的红球,但是被黑球盖住了,只有一点点边缘,根据选不到。把球弄小点就能看到了:
注:上图示例来源于https://github.com/BenVanCitters/UnityClothExample,效果如图:
8.自碰撞和互碰撞
布料碰撞使游戏中的角色服装和其他面料更加逼真。在 Unity 中,布料有几种处理碰撞的布料粒子。可将布料粒子设置为:
- 自碰撞,防止布料穿透自身。
- 互碰撞,允许布料粒子相互碰撞。
要为布料设置碰撞粒子,请在 Cloth Inspector 中选择 Self Collision and Intercollision 按钮:
更多设置细节参考官方文档https://docs.unity.cn/cn/2019.4/Manual/class-Cloth.html
还有B站视频:https://www.bilibili.com/video/BV15W411n7H3