Magica Cloth当前在物理模拟的效果上相比Dynamic Bone插件更加强大,但是随之而来的性能消耗也不容忽视。本文旨在说明通过简单修改Magica Cloth插件中的部分设置项以及调整一些参数,就能够在它的表现效果和性能之间达到一个平衡。

一、Magica Cloth简介

Magica Cloth是一款用于Unity引擎中布料模拟的插件,提供了类似于Unity的Cloth组件的功能。由于效果逼真的布料模拟运算量巨大,耗时较长,每一帧可能需要几十秒的时间来进行模拟;而在游戏中实现的布料模拟因为需要满足帧率的要求,要在几毫秒的时间内进行物理解算才不至于影响其他系统。因此,游戏中的布料模拟往往是极度简化的,以满足实时性的要求。

图片来源Magica Cloth – Magica Soft

二、Magica Cloth使用

关于Magica Cloth的使用,可以参考官方文档,这里就不再赘述。
Magica Cloth – Magica Soft

三、Magica Cloth的具体效果

Magica Cloth能够让角色的衣服、头发等受到重力、风等外部作用力的影响,表现出比较自然的运动;能够让衣服、头发在角色运动的时候随着角色的动作比较真实地改变自己的位置和形状。

Magica Cloth提供了四种基本的物理组件:Bone Cloth,Bone Spring,Mesh Cloth以及Mesh Spring。

  • Bone Cloth可以用来模拟有骨骼的头发的晃动,负载比较轻。
  • Bone Spring可以用来模拟有骨骼的胸部的简谐运动,负载最轻。
  • Mesh Cloth基于所选的网格的顶点来进行布料模拟,效果最好但是负载最重。
  • Mesh Spring可以用来模拟没有骨骼的胸部的简谐运动,负载中等。

和Dynamic Bone相比,Magica Cloth无疑功能更加强大,但是如果只是需要移动角色骨骼来实现物理模拟,Dynamic Bone也能做到比较好的结果并且性能更优。

同时,Magica Cloth相比其他物理插件功能更强大的地方在于它有相对而言比较容易调试的防穿模手段。

Magica Cloth还提供了换装系统,可以在运行时更换角色身上的服装,但是这些服装都是要在离线时做好预设,不能够在运行时修改。

四、Magica Cloth的实现原理

首先,它不依赖于Unity的物理系统,所以Unity自带的物理相关的设置不会影响Magica Cloth的表现。Magica Cloth通过Magica Physics Manager从而在运行时控制物理模拟的全部流程,所以需要在场景中存在这个Manager的时候物理模拟才会生效。

其次,它的实时运算使用了Unity的Job System和Burst Compile,能够把一些复杂的布料模拟的计算转移到工作线程中,降低了主线程的CPU占用。

当我们要使用Mesh Cloth或者Mesh Spring的时候,就需要添加额外的Render Deformer和Virtual Deformer。Render Deformer对模型的Mesh进行变形,而Virtual Deformer则是把所有的Render Deformer整合成一个虚拟Mesh并进行简化,也就是合并顶点和三角形,减少顶点和三角形的数量,降低数据量,然后把这个虚拟的Mesh对应的简化结果分配给各个Render Deformer用来进行Mesh的控制和变形。

为了能够尽可能地解决穿模问题,Magica Cloth可以针对性地设置Surface Penetration和Collider Penetration。其中,Surface Penetration在身体骨骼对裙摆等布料的运动产生影响时会比较有效,而当身体骨骼不会影响服饰的运动时,就需要使用Collider Penetration来手动设置碰撞体。Magica Cloth提供了三种Collider:Sphere、Capsule和Plane。因为主要是用于人物角色的Collider,所以常用的是Sphere和Capsule。对于部分布料模拟中分离的骨骼也可以通过设置Connection Mode进行合并,来防止运动时附加了碰撞体的躯干、大腿等从布料模拟骨骼的间隙中穿出去。

同时,除了防穿模设置外,也可以通过限制骨骼的最大位置和旋转偏移来尽可能限制骨骼节点可能的位置,这也有助于减少穿模现象的发生。

五、Magica Cloth的性能表现

在实际应用中可以发现,Magica Cloth虽然使用了Job System和Burst Compile的方法来进行物理计算,但是它造成的CPU耗时依然较高,官方文档中也提到Magica Cloth组件的耗时是稍高于Unity自身提供的Cloth组件的。

但是,Magica Cloth的优点也有很多。它使用方便:针对角色各个部位的布料模拟提供了很多的预设,例如头发的预设就包括刘海、长发、短发以及马尾等不同表现的参数,制作人员可以依据表现效果进行参数的微调,简化了参数调节的过程;为了防止穿模,它提供了一些参数用于限制骨骼节点的最大位移和旋转,同时也设计了适合于游戏中角色的常见的碰撞体,并给出了防穿模的算法。

相比于可以实现类似物理模拟的Dynamica Bone插件,Magica Cloth的缺点还是在于它较重的CPU负载。同样是对Unity-Chan头发的运动进行模拟,Magica Cloth在使用Bone Cloth组件时在整个测试过程中CPU平均占用为0.96ms,而Dynamic Bone做相同的工作只需要0.24ms。(以下测试案例使用机型均为小米8)

Magica Physica的优点则是在于提供了更加丰富的物理效果。Magica Cloth不仅能够控制角色的骨骼节点,对于角色的网格,也可以通过网格的变形来模拟出一定的物理效果,比如说能够控制角色身上的各种服饰随着角色的运动的变形,得出比较好的物理效果。

六、Magica Cloth的性能优化

为了对项目中使用的Magica Cloth组件进行针对性的优化,首先需要了解Magica Cloth的性能消耗的主要来源。为此我们同样是使用Unity-Chan的模型进行该插件的性能消耗的分析。

在官方文档中提到,Magica Cloth依赖Job System和Burst Compile进行物理计算,会在游戏运行过程中使用工作线程来完成大部分的物理模拟计算,而通过GOT Online对测试案例进行分析后可以发现,Magica Cloth插件的主要CPU耗时都会被统计到MagicaPhysicsManager这个函数下。下面将结合该函数的源代码和测试结果进行分析。

1. Magica Physics Manager工作流程
在该函数的Update中主要是检查自定义的GameLoop是否在正常工作,如果自定义的GameLoop没有生效,就执行它的初始化操作。

        private void Update(){// 对于 Unity2019.3 或更高版本,请在更新期间检查一次自定义循环注册// 已注册则通过,未注册则重新注册// 这是在 PlayerLoop 被其他资产重写的情况下的对策if (updatePlayerLoop == false){//Debug.Log("Update check!!"); InitCustomGameLoop();updatePlayerLoop = true;}}

在自定义的GameLoop中注册了afterEarlyUpdate、afterFixedUpdate、afterUpdate、afterLateUpdate、postLateUpdate以及afterRendering这几个回调。在这些回调中,主要是通过使用PhysicsManagerCompute类的方法来安排各种物理计算的Job,这些Job也是Magica Cloth插件最主要的耗时来源。

继续查看Compute中各个Job的调度,可以发现,绝大部分Job需要执行的总任务数和Particle的数量相关。

jobHandle = job.Schedule(Particle.Length, 64, jobHandle);

Particle是Magica Cloth中用来表征网格顶点或者骨骼节点的数据结构,在离线生成序列化数据时,可以为网格顶点或者骨骼节点设置Move、Fixed和Invalid三种标记,其中只有被标记为Invalid的网格顶点或者骨骼节点才不会参与物理计算,也就是说不会对上面所说的Particle.Length产生影响。因此,在制作过程中尽可能地减少Move和Fixed节点是最有效的降低物理模拟耗时的方法,当然,这样做也可能会带来一定的表现效果上的损失,需要根据实际情况来决定到底哪些节点需要进行物理模拟。

2. Delay Unscaled Time的使用与否

在Magica Physics Manager的Update选项下,根据Update Mode的选择是否使用了Delay Unscaled Time,Compute的计算方式有所不同。

  • 不使用Delay Unscaled Time时
            if (useDelay == false){// 即时OnPreUpdate.Invoke();Compute.UpdateTeamAlways();Compute.InitJob();Compute.UpdateReadBone();Compute.UpdateStartSimulation(updateTime);Compute.UpdateWriteBone();Compute.UpdateCompleteSimulation();Compute.UpdateWriteMesh();OnPostUpdate.Invoke();}
  • 使用了Delay Unscaled Time后
            if (useDelay){// 延迟执行OnPreUpdate.Invoke();Compute.UpdateTeamAlways();Compute.InitJob();Compute.UpdateReadWriteBone();Compute.UpdateStartSimulation(updateTime);Compute.ScheduleJob();Compute.UpdateWriteMesh(); // 将先前的结果应用于网格//Debug.Log($"Delay Job! F:{Time.frameCount}");}

不同的计算方式也导致了最终表现上的差异。使用Delay Unscaled Time后,因为计算的完成发生在渲染之后也就是在afterRendering回调中,所以实际的物理模拟的结果会比画面慢一帧。为了解决画面和物理不同步的问题,Magica Cloth通过上一帧和当前帧的物理模拟结果进行插值,从而得到一个预测的结果同步给下一帧。

// 未来预测float ratio = unityPhysics ? fixedFutureRatio : normalFutureRatio; // 因骨骼更新模式而异                        pos = math.lerp(oldPos, pos, 1.0f + ratio * moveRatio);rot = math.slerp(oldRot, rot, 1.0f + ratio * angRatio);rot = math.normalize(rot);bonePosList[index] = pos;boneRotList[index] = rot;// 记录未来的预测futurePosList[index] = pos;futureRotList[index] = rot;

显然,这样做会导致在碰撞检测等物理效果上出现一定的问题,但是由于它在性能消耗上更加优秀,所以可以说是非常重要的优化手段。如果对画面表现和物理结果的同步性和防穿模的要求并不是非常高,完全可以选择延迟更新的模式。在测试案例中,我们对同一个场景使用Delay Unscaled Time更新模式和非Delay更新模式进行了对比,结果表明Delay Unscaled Time更新模式下,插件的耗时大幅度降低。

  • Delay Unscaled Time更新模式

  • 非Delay更新模式

3. Merge Vertex Distance的选取

在使用Mesh Cloth或者Mesh Spring时,在Virtual Deformer组件中可以调节Merge Vertex Distance,该距离越大,生成的虚拟网格的Partcile数量就会越少,从而在物理模拟时需要的计算量就越小。这种优化的思路仍然是尽可能减少参与物理计算的顶点的数量,从而降低耗时。测试结果也表明,改变这个值可以有效降低插件的CPU性能消耗。

  • Merge Vertex Distance取0.001时

  • Merge Vertex Distance取0.01时

  • Merge Vertex Distance取0.1时

4. Use Skinning的使用与否

同样是在Virtual Deformer组件上需要关注的是Use Skinning选项是否需要勾选。

            if (use && IsSkinning && IsChangeBoneWeights && vertexCalc){// 顶点权重变化//Debug.Log("Change Mesh Weights:" + mesh.name + " buff:" + bufferIndex + " frame:" + Time.frameCount);MagicaPhysicsManager.Instance.Mesh.CopyToRenderMeshBoneWeightData(MeshIndex, mesh, sharedMesh, bufferIndex);IsChangeBoneWeights = false;}

如果勾选了Use Skinning,则需要对所有顶点的骨骼权重进行重新赋值,在官方文档中也提到,取消Use Skinning可以极大地减少物理计算的负担。它的限制在于当取消了Use Skinning选项后,网格只会受到影响程度最大的Virtual Deformer的影响,可能在一定程度上会影响最终的表现,但是如果对于一个网格的Render Deformer只在一个Virtual Deformer中使用的情况下则可以放心地取消该选项的勾选。勾选和取消勾选的测试结果如下。

  • 勾选Use Skinning

  • 取消勾选Use Skinning

5. Normal And Tangent Update Mode的选择

在使用Mesh Cloth或者Mesh Spring时同样需要关注的是Normal And Tangent Update Mode的选择。

        public enum RecalculateMode{None = 0,// 每帧更新法线UpdateNormalPerFrame = 1,// 每帧更新法线和切线UpdateNormalAndTangentPerFrame = 2,}

如果在渲染中并不要求持续更新网格的切线或者法线数据,可以把该选项设置为None,减少不必要的计算。

            if ((use || IsChangePosition || IsChangeNormalTangent) && vertexCalc){// 重写Mesh// 将meshBuffer设定为mesh(工作量巨大)// ★目前为止除此以外别无他法,经过思考有2个可以避开的办法:// ★(1)等待未来版本的Unity上进行支持// ★(2)使用computeBuffer对Shader顶点进行合批(很快,但是因为必须使用特殊Shader所以兼容性较低)MagicaPhysicsManager.Instance.Mesh.CopyToRenderMeshLocalPositionData(MeshIndex, mesh, bufferIndex);bool normal = normalAndTangentUpdateMode == RecalculateMode.UpdateNormalPerFrame || normalAndTangentUpdateMode == RecalculateMode.UpdateNormalAndTangentPerFrame;bool tangent = normalAndTangentUpdateMode == RecalculateMode.UpdateNormalAndTangentPerFrame;if (normal || tangent){MagicaPhysicsManager.Instance.Mesh.CopyToRenderMeshLocalNormalTangentData(MeshIndex, mesh, bufferIndex, normal, tangent);}else if (IsChangeNormalTangent){// 返回mesh.normals = sharedMesh.normals;mesh.tangents = sharedMesh.tangents;}IsChangePosition = false;IsChangeNormalTangent = false;}

三种选项下的测试结果如下所示:

  • None

  • UpdateNormalPerFrame

  • UpdateNormalAndTangentPerFrame

七、Magica Cloth总结

Magica Cloth当前在物理模拟的效果上相比Dynamic Bone插件更加强大,但是随之而来的性能消耗也不容忽视。本文旨在说明通过简单修改Magica Cloth插件中的部分设置项以及调整一些参数,就能够在它的表现效果和性能之间达到一个平衡。

除了上文提到的一些性能瓶颈之外,如果在项目中使用了Magica Cloth提供的Collider Penetration,以及设置了各种位置和旋转的限制时也会导致一定的性能消耗,但它们的影响不及上一节中提到的几个重要的优化点。建议在对Magica Cloth进行性能优化时先尝试通过上述的办法进行修改,再去关注穿模和位置旋转限制等相关设置。

Magica Cloth相关推荐

  1. Magica Cloth服装模拟插件分享

    Magica Cloth服装模拟插件分享 前言 Magica Cloth 是一款高速的布料模拟器,完全使用自己的物理引擎,因此,它完全不会干扰Unity的物理系统. 官方链接地址 一 安装 使用对应的 ...

  2. Unity 布料模拟插件Magica Cloth

    依赖包 Magica Cloth 使用 Job System 和 Burst compiler 加快布料模拟,所以需要先安装这两个依赖包 Burst 可以直接下载 在这里插入图片描述 Job Syst ...

  3. Magica Cloth笔记——1

    文章目录 前言 一.Magica Cloth是什么? 二.主要组件 总结 前言 系统概览: 关于Magica Cloth的主要组件:MagicaPhysicsManager.MagicaBoneClo ...

  4. Magica Cloth 属性介绍

    1:Magica Bone Cloth 2:在Root List中,可以分别设置模拟数量和需要模拟的根骨骼 要进入编辑模式,请单击布料组件的Start Point Selection(当你进入编辑模式 ...

  5. 《Unity Magica Cloth从入门到详解》之(6)换装

    文章目录 一.Avatar和Avatar配件 二.将MagicaAvatar 组件附着到身体 三.将MagicaAvatarParts 零件组件附着到头发,面部和衣服上 四.准备主体和8个零件作为样本 ...

  6. 《Unity Magica Cloth从入门到详解》之(5)MeshSpring

    文章目录 一.MeshSpring网格弹簧设置 二.渲染变形器/虚拟变形器设置 三.网格弹簧设置 四.调整弹簧参数 五.左右摇晃胸部 六.网格弹簧调整指南 一.MeshSpring网格弹簧设置 Mes ...

  7. 《Unity Magica Cloth从入门到详解》之(8)视野外剔除系统

    文章目录 一.概述 二.剔除模式设置 三.与动画联动 四.用于剔除判断的渲染器 五.检查剔除状态 六.注意事项 一.概述 通过使用剔除系统,可以停止未在相机上绘制的角色的交叉模拟. 这将大大提高性能, ...

  8. 《Unity Magica Cloth从入门到详解》之(7)防穿模

    文章目录 一.概述 二.对于MeshCloth类型 1.当裙子包含主骨骼的权重时 2.当裙子不包括主骨骼的权重时 三.对于骨布BoneCloth 四.Surface Penetration表面渗透 五 ...

  9. MMD->Unity一站式解决方案

    1. 准备工作 1. 准备模型 你需要准备来自MMD的模型,或任意其他可在Unity中使用的模型 获取来自MMD的模型方法有很多,比如 bowlroll .aplaybox(模之屋). 针对其他模型的 ...

最新文章

  1. ubuntu 12.04 添加 IP并配置DNS
  2. for表达式的语句执行顺序?
  3. 【必看】做了3年运维却不涨薪?那是你还没get这个技能
  4. 【工具】ubuntu下在百度云文件
  5. Python缓存类实例
  6. 一文读懂架构整洁之道(附知识脉络图)
  7. ADF12C viewScope,pageFlowScope,requestScope,backingBeanScope
  8. php怎么在html上得到input值,怎么把一個php頁面的值傳到另一個html表單中的input里面去...
  9. MSDN2008下载
  10. 如何在工作中设定和使用 SMART 目标
  11. 华为路由器接口编号与接口的对应关系
  12. 微信访问IP地址页面出现的问题
  13. 【图数据库】GalaxyBase 查询优化之索引
  14. NOMS管和PMOS管的区别
  15. 【模拟电路】波形产生与变换设计(555+运放)
  16. 大学是人生的关键阶段
  17. 第11章 网络物理隔离技术原理与应用
  18. 2020年回顾与2021年展望
  19. linux机器查看物理内存,Linux系统中下查看内存的方法
  20. latex中怎么在符号正上和正下方编写公式

热门文章

  1. ubuntu18.04.2LTS下如何用五笔输入法 --Linux
  2. 关于图像处理和Python深度学习的教程:第一部分
  3. js拼接字符串时数据类型的隐式转换
  4. java季度第一天_java获取某月,某季度的第一天和最后一天
  5. 移动质监执法系统项目开发与分享
  6. 陈凯:面向未来的多云管理平台
  7. 【Halcon】halcon中的常用算子的中文说明
  8. 几何工具引擎(geometry tool engine)
  9. 瑞典品牌Happy Plugs推出专为3至15岁少年设计的新耳机
  10. android代码删了怎么恢复,android手机系统程序误删了怎么恢复?