UPL7-5——碰撞体缩放,位置,质量
UPL7-5——碰撞体缩放,位置,质量 尽量保证物理对象的缩放大小 尽量保证物理对象的缩放为(1,1,1),原因: PhysX 的很多容差(接触偏移、皮肤宽度、求解步长等)是以 1unit = 1m 的数量级进行默认调参的 把物体做得过小(< ~0.1m)或过大(> ~10–50m),更容易出现穿透、抖动、关节数值不稳等问题 非均匀缩放还会让碰撞几何与惯性张量的计算更复杂,稳定性更差 因此为了避免增加物理计算压力和稳定,建议保证物理对象的缩放不变 尽量保持对象不要距离世界空间原点位置过远 建议保持对象在世界空间的位置尽量接近世界空间原点 (0,0,0),因为距离(0,0,0)越远,32 位浮点的小数精度越差,出现距离现象 距离现象会表现为渲染抖动、碰撞抖动、关节发疯等等 比如:如果是超大场景的游戏,玩家可能走数万米,那么有可能在远处时产生奇怪的物理表现 建议:我们可以秘密地将玩家传送到世界空间的原点(0,0,0), 可以在玩家...
UPL7-4——物理系统基础设置
UPL7-4——物理系统基础设置 物理系统基础设置 我们可以在 Project Settings 中对物理系统进行一些基础设置, 这些设置看起来只是和物理系统相关,但是实际上其中有很多的参数都会实实在在的影响我们的性能, 因此,了解这些基础设置,对于我们优化性能也有一定的帮助! 解算器 解算器(Solver)在 Unity 物理系统里其实是指物理系统里负责解方程的模块,就是 Unity 物理中用来处理碰撞,关节约束的方程求解器 它决定物体在发生接触后该怎么调整位置和速度,迭代次数越多越稳定,代价是 CPU 的消耗也更高(迭代指的就是解算器的计算次数) 在物理模拟中,碰撞检测只是发现 物体 A 和物体 B 重叠或接触,检测到重叠或者接触后,接下来要处理两个问题: 它们要分开多少 它们的速度,角速度要怎么调整? 这就涉及到一系列约束条件: 碰撞不允许重叠,需要位置约束 摩擦,弹性系数要生效,需要速度约束 关节要维持结构,需要关节约束 这些约束本质上会形成一组线性方程和不等式,解算器就是负责解这些方程,求出新的位置与速度 举例:解算器在 Unity...
UPL7-3——碰撞层矩阵
UPL7-3——碰撞层矩阵 物理检测中的广义阶段和狭义阶段 具体概念详见:UPL2-9——Physics 模块 在物理引擎中,碰撞简称一般分两步: Broadphase(广义阶段 | 粗检测阶段 | 宽阶段检测) 目标:快速找出可能会相撞的一对对象 方法:用简单的边界盒(AABB:Axis-Aligned Bounding Box,轴对齐包围盒)进行检测 特点:非常快,但不精确。它不会算真的撞没撞,只负责筛选出候选对 Narrowphase(狭义阶段 | 精检测阶段 | 窄阶段检测) 目标:对 Broadphase 找到的候选对象,进行更精确的检测 方法:用实际碰撞体形状(球体、胶囊体、多边形、网格等)计算真正的接触点 特点:精确但耗时大 因此在进行碰撞检测时,Broadphase 就像安检口的初筛,它是第一步会做的事情 优化物理引擎消耗的主要思路 物理引擎的 CPU 消耗,本质上就是碰撞检测和物理解算的计算量 Unity...
UPL7-2——时间步长和最大允许时间步长
UPL7-2——时间步长和最大允许时间步长 Unity 物理系统中的更新机制 Unity 中的 3D 物理系统基于 Nvidia(英伟达)的 PhysX,2D 物理系统基于开源项目 Box2D Unity中 对他们进行了封装,我们不需要知道内部是如何执行的,只要调用 Unity 相关API,既可以让两个物理引擎解决方案以相同的方式运行 物理系统的执行机制中,最重要的就是 时间步长(Time Step) 的概念 时间步长在 Unity 中我们一般称为 固定更新时间步长,指的是 物理世界 更新的固定时间间隔 即每隔多长时间更新一次物理逻辑,在 Unity 中默认为每 20 ms(即 0.02 秒,50 Hz) 更新一次 我们可以在 Project Settings ——> Time ——> Fixed Timestep 中进行设置 注意: 物理逻辑是独立于帧率的,不以帧为准,而是严格以固定时间步长为准,一帧里可能执行 0 次、1 次、甚至多次物理循环 即...
UPL7-1——Physics Debugger
UPL7-1——Physics Debugger Physics Debugger Physics Debugger 是 Unity 提供的一个 物理系统可视化调试工具 它不会改变场景中的物理行为,而是通过图形化的方式把: 碰撞体(Collider) 刚体(Rigidbody) 触发器(Trigger) 关节(Joint) 接触点(Contact) 射线检测(Raycast) 范围检测(Overlap) 等信息直观显示在 Scene 视图里 帮助开发者快速定位物理相关的问题,它严格来说并不是性能检测工具,而是用于定位物理碰撞表现问题的,比如: 定位为什么碰撞没有触发 为什么子弹打不中敌人 关节为什么拉扯异常 等等问题的 点击工具栏 ——> Window ——> Analysis ——> Physics Debugger 即可打开相应窗口: 初始 Physics Debug 窗口 物理调试窗口中,主要由五部分组成: Info(信息) 显示被选中物理对象(通常是...
UPL7——物理引擎相关
UPL7——物理引擎相关 物理相关性能分析详见:UPL2-9——Physics 模块、UPL2-10——Physics (2D) 模块 Physics Debugger(物理系统可视化调试工具,主要观察碰撞表现信息,而不是性能分析) 工作机制相关 时间步长和最大允许时间步长(物理世界的更新间隔时间相关) 碰撞层矩阵(控制基于层的物理碰撞,可以将两个不可能发生物理碰撞的层的物理碰撞勾选给取消掉) 物理系统基础设置(包括解算器,碰撞检测,模拟模式等设置相关,包含 2D 和 3D 物理相关的各个全局设置项) 碰撞器相关 碰撞体缩放,位置,质量(物理对象的缩放应保持 (1,1,1),不能距离世界原点过于远,不能过轻或过重,会发生物理交互的质量比最好控制在 20:1 以下) 避免复杂碰撞体类型(简单碰撞体的性能消耗低于复杂碰撞体,当出现物理相关性能瓶颈时可以从简化碰撞体类型入手) 刚体相关 碰撞检测相关
UPL6-7——手动合并网格
UPL6-7——手动合并网格 前置知识:UED——Unity编辑器拓展 本章代码关键字 12345678910111213CombineInstance // 网格实例化参数CombineInstance.mesh // 网格属性CombineInstance.subMeshIndex // 使用的子网格索引CombineInstance.transform // 将网格的顶点变换到某个空间坐标系下的4*4空间变换矩阵transform.worldToLocalMatrix // 获取可以将点从世界空间转换到本地空间的矩阵transform.localToWorldMatrix // 获取可以将点从本地空间转换到世界空间的矩阵mesh.vertexCount // 获取网格的顶点数量mesh.indexFormat // 网格的索引格式,可以是uint16或uint32,默认是uint16IndexFormat.UInt16...
UPL6-6——DrawCall 优化方案对比
UPL6-6——DrawCall 优化方案对比 DrawCall 优化方案对比 方案 动态批处理 静态批处理 GPU Instancing SRP Batcher 原理 运行时 CPU 每帧合并网格运行时每帧动态合并小型网格的顶点数据 构建或首次运行时 CPU 合并网格运行前合并静态物体的网格为一个大网格 GPU端批量绘制相同物体一次 DrawCall 提交共享网格和实例数据,GPU 并行绘制多个对象 不减少 DrawCall,是将物体、材质参数缓存到 GPU,减少 CPU 开销不合并网格,通过持久化 GPU 缓冲区优化材质、对象数据提交,降低 DrawCall 的CPU 开销 限制 网格顶点数小于 225 或 300 (Unity 2021 之前为 300) 并且顶点属性小于 900相同材质实例禁止镜像缩放、蒙皮、实时投影等 必须标记为静态批处理对象相同材质实例物体不可移动、旋转、缩放每个静态批次最多可以包含 64,000 个顶点 相同网格材质需启用 GPU Instancing 功能,并且支持该功能不支持蒙皮网格渲染器等等 仅限 SRP 管线(URP /...
UPL6-5——SRP Batcher
UPL6-5——SRP Batcher SRP Batcher SRP Batcher(Scriptable Render Pipeline Batcher)是 Unity 在可编程渲染管线,比如 URP、HDRP 中提供的一项 CPU 优化技术 主要目的是用于降低 材质切换 带来的开销 主要解决的问题: 每次 DrawCall 不仅要告诉 GPU 画哪个网格,还要上传 材质常量(Shader 参数), 不同物体哪怕使用同一个 Shader,但只要材质不同,CPU 就要重新设置常量缓冲区(Constant Buffer),这一步就叫做 SetPass SetPass 开销很大,在复杂场景里,CPU 花在切换材质的时间常常比真正发 DrawCall 还多,而 SRP Batcher 就是用来解决这一问题的 主要原理:Unity 在 GPU 显存中为 Shader 的常量缓冲区分配了两个区域: 材质缓冲区: 存储材质相关的参数(颜色、贴图索引 等数据),存放在 GPU 可缓存的大缓冲池里,不用每次切换材质都重新上传 物体缓冲区: 存储物体相关的参数(变换矩阵、光照探针...
UPL6-4——GPU Instancing
UPL6-4——GPU Instancing GPU Instancing GPU Instancing 就是 GPU 实例化的意思,它是一种减少 Draw Call,提高渲染效率 的技术,主要用来批量绘制大量相同的网格(Mesh)对象 它的主要原理,当开启 GPU Instancing 后,Unity 会将一份 网格 和 材质 上传到 GPU,并且还会传递一批 实例数据(里面包含每个物体的位置、旋转、缩放、颜色等等) GPU 收到数据后,会通过对象的实例化 ID 找到对应的参数,动态计算世界坐标,让 GPU 在一次 DrawCall 中绘制出许多相同的对象 说人话:GPU Instancing 利用 CPU 一次 DrawCall 告诉 GPU 的数据,GPU 自己根据数据绘制 N 个不同但是材质相同、网格相同的对象 比如:CPU 只通过一次 DrawCall 告诉 GPU 要绘制树,同时告诉了 GPU 这里 n 棵树的坐标、旋转、缩放、颜色等等数据,GPU 就利用这些数据批量的绘制 n 棵树 注意: GPU Instancing 和 动态和静态批处理...
