/images/avatar.png

Papalqi

UE4物理动画参数

首先我们打开物理资产: 影响物理动画的是两个,一个是Profile里面物理动画的配置,还有一个是本身Body 上面的配置 一. Body的设置 Mass ,默认是根据你Body上的体积自动计算的,我们可以更改。最终影响的是惯性 LinearDamping:线性阻尼。控制Body的线性速度减缓强度。值越大,速度减小越快。 AngularDamping:角速度阻尼。控制Body的角速度减缓强度。值越大,速度减小越快。 (以上两个数值,若启用PhysicalAnimationProfile,一般不再设置这两个数值,Profile的值也影响该效果) Enable Gravity:是否启用重力。关闭后不受重力影响,只受Body的惯性影响。 CollisionReponse:是否和外部物体碰撞。需要和外部物体碰撞时打开,如在人群中穿行和碰墙壁 二. Limit的设置 原则上是根据人体骨骼活动范围设置limit,并且所有动作都应在limit中运动。为了方便,可把所有limit设为free,通过Physical Animation Profile来约束,Profile无法满足的,再去设置个别骨骼的limit,如Spine。 三. Physical Animation Profile 打开Profile 选择一个已经有的prfile,这个名字对应的配置是可以在蓝图里指定的。 选择完成后,就可以看不同的刚体对应的物理参数 Is Local Simulation:是在世界空间还是在局部空间,判断移动Kinematic时是全局还是相对父Body的。目前从代码来看我们用世界空间的比较好。 Orientation Strength:用于更正方向误差的力。值越大,越靠近动画的角度 Angular Velocity Strength:用于更正角速度误差的力。值越大,速度稳定(向动画靠近)的越快。 Position Strength:用于更正线性位置误差的力。仅可用于非局部模拟。值越大,越靠近动画的位置。 Velocaty Strength:用于更正线性速度的力。仅可用于非局部模拟。值越大,速度稳定(向动画靠近)的越快。 Max Linear Force:用于更正线性误差的最大力。(设为0) Max Angular Force:用于更正角度误差的最大力。(设为0) 四.Constraint Profile 功能:局部控制。关节驱动身体靠近动画,靠近动画的姿势,而不影响Body的属性。如果靠PhysicalAnimationProfile驱动,会导致Body过于僵硬无法移动,ConstraintProfile解决了这一个问题,但运动时需要PhysicalAnimationProfile去稳定Body的位置(全局的)。 原理:设置Constraint的Motor,setDrive驱动关联的两个Body到达动画的相对Rotation。 SkeletalMeshComponent需要设置Update Joints From Animation为true. Angular Drive Mode需要设置为Twist and Swing,Motor才会生效。 Target Orientation: 不必设置,Update Joints From Animation会取动画来设置该Orientation。

Chaos破碎性能分析

默认情况下,Chaos没有开启多线程,我们将两种方式对比.开启TaskGraph没有明显变化 一.基础测试 1.1 没有碎块 没有碎块的话,我们的性能开销是0.1ms 开启TaskGraph没有明显变化 1.2 100块碎块 当我们100块的时候,上升到了5ms 1.3 500块碎块 上升到了20ms 1.41000块碎块 上升到了60ms 测试案例,将一个box分为1000块。 二.修改参数 2.1修改Iterations 我们看到,绝大部分的物理性能的消耗不出所料是在计算物理位置的EvolutionAndKinematicUpdate上面。 集中在AdvanceOneTimeStep上面。在物理引擎中,我们的帧数其实要比物理引擎的帧数低很多,物理引擎将每帧分成更小的单位Step,每一步来判断是否发生了碰撞,如果发生了碰撞则会发生反弹等其他操作。 对于1000块,我们修改 当Iterations变为5时,48ms。为2时,28ms,为1时,25ms。 2.2增加cluster 我们Iterations的基础上,将1000块分组。增加Cluster的效果非常好,虽然我们破碎分为10个Cluster的话和没分的时候差不多。但是我们分为100个Cluster时 我们分为200个: 这里的分簇操作控制碎裂网格体的视觉质量和性能。破坏建筑物等对象时,级别1通常需要少量簇(或较大碎片),随着级别的增加会发生更多破坏(较小碎片)。 最初碎裂时无需数千碎片以进行优化,而是在建筑物倒下时落下单独碎片。 优化的另一选择是定义要碎裂的 最大簇级别(Max Cluster Level) 可以看出来,分Cluster对整个的破碎非常的有帮助。 合理的分簇能够极大的减少性能开销,我们进行多级的分组 帧数能稳定在70fps 结论 就算是调整到比较廉价的方式,其本身依旧还是开销巨大,对整个场景的破坏极具考验。

Chaos代码结构剖析

本片文章深入剖析Chaos的代码结构。 一.代码结构 Chaos的核心代码存储在Source/Runtime/Experimental中 而一些之外的代码都是以插件的形式存在于引擎之中。InteractiveToolsFramework并不属于Chaos的模块。 ChaosCore封装了一些基本的数据结构,有Array,Vector,Matrix,其考虑到了没有Unreal基本数据结构支持时应当如何处理。 Voronoi是计算几何术语,在二维空间中的一种空间划分的方案,对于离散点的空间划分中,其具有每条边到点的距离是相等的特点。 GeometryCollectionEngine,实现资源GeometryCollection的声明和应用,还有Gameplay中使用的Component和Actor实现了GeometryCollectionActor\GeometryCollectionComponent\GeometryCollectionComponent等功能。其作为UE的破碎功能和Chaos的结合实体。 FieldSys,实现控制破碎过程中使用的场的功能。如力场,sleep场,kill场等等。 ChaosVehiclesEngine,使用Chaos实现的载具功能,目前处于实验状态。 ChaosSolverEngine,每个破碎功能都必须有一个解算器,如果我们不声明的话,我们会使用默认的解算器。 Chaos,所有的物理计算,进阶和高端的操作都在这个模块当中 在引擎中,physx和chaos是无法兼容进行使用的,在编译阶段就使用宏来进行了所有的隔离操作,以保证上层的使用对底层的实现无法感知。PHYSICS_INTERFACE_PHYSX和WITH_CHAOS是完全互斥的两个宏。 当然,一些核心的调度代码存在Engine/Physics/Experimental中。 主要数据结构 我们知道,我们使用所有破碎都需要通过使用UGeometryCollectionComponent来实现,而我们的UGeometryCollectionComponent对应的破碎数据则是存储在 UGeometryCollection 中,我们在编辑器中指定和配置的都是这个数据。除了UGeometryCollection外,还有一个UGeometryCollectionCache的数据,我们可以使用UGeometryCollectionCache的数据进行与烘培减少在运行时的实时计算。 FPhysScene_Chaos,作为物理世界的物理线程与主线程的桥梁,所有与物理世界的交互都在这里进行。 TPBDRigidsSolver,真正进行物理计算的数据结构,自己玩自己的,只经过FPhysScene_Chaos进行同步交流。如果仅有一个Solver的话,我们所有的物理计算都是在一个空间中和之前是没有区别的;如果我们对场景中不同的物体指定使用不同的物理解算器,不同解算器之间是没有办法进行通信的,可能这在某些情况下会有这种特殊需求。 建立物理状态 对于破碎来讲,UGeometryCollectionComponent与一般的Component一样,也是在注册时进行物理数据的注册和提交。而其他的物理和Phx一样,上层接口上是无感知的。 从UActorComponent开始,会在注册时调用CreatePhysicsState。根据是否需要生成OverlapEvent,分为两个不同的分支。 如果不需要OverlapEvent,我们获得Wolrd 的PhysicsScene的DeferPhysicsStateCreation,延迟的创建 1 WorldPrivate->GetPhysicsScene()->DeferPhysicsStateCreation(Primitive); 对于需要的,我们将调用OnCreatePhysicsState来进行。 对于每个拥有Mesh 的Component来说,必须含有物理数据,也就是UBodySetup才能够确定其物理世界的表示方案,所以只有保证有其正确的BodySetup。 之后,会加入到PhysScene的DeferredCreate PhysicsStateComponents中。对于其后续的操作则在PhysScene阶段再进行介绍。值得说明的是,我们的初始化操作其实是针对其内部的BodySetup,我们初始化完成BodySetup后,在Scene中依旧会调用OnCreatePhysicsState来生成PhysicsState。 跟渲染一样,由于都是不同线程间进行,根据Unreal 的设计原则,不同线程之间都需要一个Proxy来进行通信和代指,从而保证线程间的安全。 对于Chaos物理系统而言,拥有自己的物理代理。 所有的物理代理都是继承于TPhysicsProxy。其类型有 FSkeletalMeshPhysicsProxy,对SkeletalMesh 的物理代理 FStaticMeshPhysicsProxy,对StaticMesh 的物理代理 TGeometryCollectionPhysicsProxy,对破碎物体的物理代理 TJointConstraintProxy,对约束节点的的物理代理 等等。 每个物体的物理状态的更新OnCreatePhysicsState的时候。在OnDestroyPhysicsState的时候销毁,这两个也分别是在组件创建和销毁的时候进行的。 当我们创建完成一个PhysicsProxy,我们将其加入到PhysicsScene中来。使用FPhysScene_Chaos::AddObject来进行,物理代理和Component的对应关系将会被记录下来。但是其物理真正加入到解算器中并一定是在这里。 在UPrimitiveComponent中首先会根据UBodySetup建立BodyInstance之后调用InitBody,将自己的物理代理加入物理世界。当然我们的破碎由于不是BodyInstance能代表的,其实我们在生成TGeometryCollectionPhysicsProxy加入Scene的时候,注册到物理世界的。 普通的BodyInstance注册到解算器 对于一般的BodyInstance,不管是StaticMesh还是SkeletalMesh,都是使用BodyInstance来表示的,所以他们都是在BodyInstance的InitBody,添加到物理世界中。 调用InitDynamicProperties_AssumesLocked。 GeometryCollection注册到解算器 对于TGeometryCollectionPhysicsProxy来说,我们需要定义三个不同的函数: 1 2 3 FInitFunc InInitFunc; FCacheSyncFunc InCacheSyncFunc, FFinalSyncFunc InFinalSyncFunc 初始化函数,这里主要是处理拥有Cache的破碎,Chaos是支持预先烘培的Cache模式,如果我们指定了Cache模式,我们将会在这里进行初始化操作.

Chaos使用文档

在这里我们将跳过如何开启、编译、下载的基本步骤。并且虽然Chaos是一整套的物理引擎,本文则不对其与Phx的通用功能做出特殊说明而只针对其本身的破碎系统 资源与编辑器 GeometryCollection 我们进行破碎的第一步就是将Mesh转化为Chaos可识别的GeometryCollection资源,GeometryCollection是Chaos的物理资源。 Mesh要求 生成GeometryCollection并不是所有的Mesh都符合要求,并且为了达到更高的效率,我们依旧需要Mesh制作中符合某些特定的标准才可以。 模型需要封闭(Watertight),无交叉(Non-Intersecting)。 对于凸物体来说其分割将会更加的灵活能施加更多的控制,所以对于复炸的模型我们需要将他的Mesh拆分开,分别配置其破碎,最后通过蓝图将这些东西聚集成整体。 我们的轴向选择需要符合Unreal的Gridding Ststem的要求,这样我们控制Width和Height的时候才能更加的高效。 要考虑的另一个概念是 材质 指定,即使模块的材质相同,也应每个材质类型应用唯一的材质ID。这样在碎裂时可生成第二个材质ID,然后即可指定适当的内部材质。 在下方视频中,几何体集由两个网格体组成,而这两个网格体共享相同纹理,但使用两个不同的材质类型。因此,石料和混凝土的内面均可使用唯一材质;如果一种材质已被使用,则可将一个材质ID指定到内面。 将多个不同的Mesh整合在一个GeometryCollection中,将会使得如果有相同材质的话会共享材质并且降低DC。 多个Mesh是可以结合成为一个GeometryCollection,虽然小的物体在空间中的拜访非常灵活,但是会造成高的DrawCall,可见的接缝,并且十字交叉的重复。大型的Mesh会导致灵活性降低,但是会隐藏接缝。 创建GeometryCollection 我们使用的所有的Chaos的破碎都需要存储在Geometry Collection的资源内。 Collision Settings, Collision Type:我们的Collision Type一共有两种,一种是Implicit-Implicit一种是Particle-Implicit。他是和Implicit Type有着密不可分的关系。使用Level Set Volumes时,应将 Collision Type设为Particle-Implicit。也可将其设为 隐式-隐式(Implicit-Implicit),但其在后台仍会检查隐式表面的碰撞粒子。 Implicit type:总共有四种,盒体、球体或胶囊体和Level Set Volumes。盒体以类似于边界框的形式包裹形体,而球体和胶囊体则放置在刚体内部来适应空间。 在模拟期间,这能加快计算速度并降低内存占用率,但会降低精度。Level Set Volumes,此类体积使用体素化网格对刚体采样,并生成几何体的有向距离场。Level Set Volumes精度更高,可调整的性能,不过内存使用更高 Min Level Set Resolution Max Level Set Resolution MinCluster Level Set Resolution MaxCluster Level Set Resolution Collision object Reduction percentage:如Box之类的碰撞,其类似于外包围盒的那种类型,一般来说包围盒都会比破碎物体本身要打,所以我们在模拟一开始包围盒之间就会交叉,调整整个参数将会降低。 破碎系统 我们将在这里来选择我们的破碎系统 碎裂方法有多种不同类型,结合不同技巧便能产生更为有趣的破坏效果。可尝试使用不同选项和设置来实现理想效果。 使用Shift-B 可以看到Bone Color,当你选择了一个GeometryCollection.

UE4 物理系统实现

虚幻引擎4使用 PhysX 3.3 物理引擎来模拟物理效果。所有物理运动(坠落或受力的物理形体)以及碰撞(物理形体的相互作用)都由 PhysX 管理。 一.Physx 1.1Physx简介 UE4.21前的版本采用的是NVIDIA的PhysX做为其默认的物理引擎,用于计算3D世界的碰撞查询与物理模拟。自4.21版本开始重构了代码调用,兼容使用Chaos物理系统,4.26才会实装,如要使用的话是需要自己构建的。 由于Epic 和NVIDIA的PY交易。Epic为UE4开发者们提供PhysX 3.3.3的基于CPU实现的二进制代码访问权,而且还包括其C++源代码访问权,以及布料库和可破坏物体库。 现在除了可以获得虚幻引擎4的完整C++源代码外,还可以查看和修改此PhysX代码。 参见:https://ue4community.wiki/legacy/physx-integrating-physx-code-into-your-project-ryzw4tj3 Physx文档:https://gameworksdocs.nvidia.com/PhysX/3.3/PhysXGuide/Index.html 1.1.1使用debug 模式检测物理 UE4 使用NVIDIA 的PhysX 3.3物理引擎来模拟物理效果,使用 APEX 模拟 destruction 和 clothing。对于PhyX,它对于UE4来说就是一个提供输入然后获取输出的黑 盒,不过可以通过NVIDIA提供的PhysX Visual Debugger(PVD)来进行可视化调试在编辑器运行游戏 输入pvd connect我们就可以得到实时的物理调试结果。 整个debug软件是比较重的,功能众多,如果大家在项目中遇到了一下物理上的性能问题,强烈建议可以打开pvd看下场景里的动态rigidbody情况,碰撞穿插解算的复杂度,一般严重的性能问题都是在这方面的。 1.1.2基本数据结构 PxPhysics:用来创建Physx各种实用组件,像场景,Shape,Rigidbody,布料,粒子系统等。 PxScene:物理场景,是碰撞盒组件的模拟环境,它的创建是根据PxSceneDesc属性来的。一个大型系统可以有多个场景,不同场景的组件相互不影响,比如UE4,使用了2个场景,用来模拟同步和异步的物理模拟功能。 PxSceneDesc:有如下属性: gravity 重力大小和方向, PxSimulationEventCallback 模拟事件回调, PxContactModifyCallback 碰撞解算修改回调, PxCCDContactModifyCallback CCD的碰撞解算修改回调, filterShader 全局的碰撞分类处理函数, cpuDispatcher Cpu线程分配器 PxCooking:碰撞盒得有形状,我们知道物理引擎里碰撞盒不仅仅是只有胶囊体,长方形,球形,还有凸包体,复杂的静态地表碰撞盒,三角形面片构成的碰撞盒。对于比较复杂的碰撞盒,Phyx支持用PxCooking类接受面片数据,然后create出可以使用的碰撞mesh。 Rigidbody: 它首先是Actor,作为Scene的基础实体,然后可以分成静态的和动态的,静态的如房子,各种场景部件,有自带的预处理功能,处理碰撞等运算性能高很多,动态的像人,车,可以运动,但性能会差一些,动态Rigidbody里用的比较多的是PxRigidDynamic,而Articulation是专门给类似布娃娃这样的系统设计的。 PxShape:SimulationFilterData 这个是做碰撞模拟类别划分的,这边设定好SimulationFilterData,在场景下的filterShader进行区分,可以控制哪些碰撞shape之间是可以相互进行碰撞计算的。 PxMaterial:DynamicFriction,StaticFriction动摩擦,静摩擦,Restitution弹性系数,FrictionCombineMode 摩擦力计算的方式,比如两个物体碰撞了,摩擦力双方不同,可以选择取最小的,最大的,或者平均一下,RestitutionCombineMode,弹力计算模式,摩擦力的一样。 1.1.3几何体 UE4 里面使用的几何体完全匹配于Physx的类型。 球 胶囊体 box 平面 凸包 三角形Mesh 需要注意的问题是,凸包的在Physx里面限定的个数是255.

AR Kit sample分析

AR Kit sample分析 arkit动画模型规范 关卡蓝图流程 Live Link Plugin 使用Live Link Plugin驱动面部追踪数据,包括当前的面部表情和头部旋转,作为一个运动捕获设备来puppeteer一个onscreen charater. 概览 对比51个独立的面部位姿。这些位姿在ARKit SDK内部,每一个位姿对应面部的一个特定部分。比如左眼,右眼,嘴巴等。位姿的值在[0.0, 1.0]间变化。举例来说,如果一个用户闭上左眼,那么LeftEyeBlink会在[0.0, 1.0]之间变化。 也就是说,用户的面部自然移动时,所有的51个位姿会被SDK评估并分配一个值。UE4 ARKit集成了所有的51个位姿,通过Live Link Plugin导入到UE4中。这51个值能够驱动实时的任务面部表情。 需要做的是捕获并驱动人物的头部来确保角色内容能够使用这51个数据。这51个反馈数据在[0.0, 1.0]之间,因而十分适合驱动人物角色表情。 详情请参见: arkit动画模型规范 设置 角色设置 创建一个blend shape角色模型基于面部动画,包括51个blend shapes.理想的,这些blend shapes的命名也与Apple ARKit一致。 导入到UE4,确保导入了Blend Shapes 在DefaultEngine.ini文件中开启面部追踪。 打开项目,在项目设置中设置AR为On. 创建并应用一个Data Asset来进行面部追踪。 内容浏览器,Miscellaneous > Data Asset 选择ARSessionConfig 双击 new Asset 设置 World Alignment: Camera Session Type: Face Horizontal Plane Detecion: Off Vertical Plane Detection: Off Enable Auto Focus: Off Light Estimation Mode: Off Enable Automatic Camera Overlay\Trakcing :Off 在关卡蓝图中Begin Play后,带动Start AR Session,并设置ARSessionConfig数据。 创建一个动画蓝图,使用LiveLinkPose节点,名称为FaceAR.