UPL10-4——网格与动画资源优化

前置知识:U3L17——模型导入相关设置

网格与动画优化的核心理念

减负、精简、按需加载

  • 网格优化目标:降低顶点处理负荷和 GPU 传输负担
  • 动画优化目标:降低 CPU 蒙皮计算和内存占用
  • 核心矛盾:视觉保真度 和 CPU / GPU 性能 和 内存占用 的平衡

网格优化流程:

  1. 设置合适的压缩级别
  2. 取消 Read/Write,除非需要修改网格
  3. 开启 Optimize Mesh(优化网格)
  4. 按需使用 LOD
  5. 精简顶点数据

动画优化流程:

  1. 选择合适的压缩格式(Optimal 推荐)
  2. 设置合理的压缩质量
  3. 配置 Animator Culling 模式
  4. 按需使用 GPU Skinning
  5. 实现动画 LOD 系统

网格资源导入优化

网格导入设置是优化的第一道关卡

  1. Mesh Compression(网格压缩)

    • Off:无压缩,最高精度,绝对精确,没有任何视觉损失
    • Low:施加非常轻微的压缩。对顶点数据的精度损失几乎不可见
    • Medium:平衡压缩率和视觉质量
    • High:激进地压缩顶点数据以追求最大程度的体积缩减

    作用:目的是减小网格资产在磁盘上的文件大小以及在运行时内存中的占用
    它通过降低顶点数据的精度来实现这一目标,本质上是在内存、磁盘空间和顶点精度之间进行权衡
    压缩的不是多边形数量,而是每个顶点的位置、法线、UV 等数据的存储精度
    但是过高压缩会带来闪烁、法线接缝、法线贴图异常等等副作用
    压缩带来的问题在静态模型上往往不明显,但在骨骼动画模型上会被放大
    务必在动画状态下测试设置为 High 压缩级别的角色,观察关节处是否有抖动

    建议:

    • 重要角色、主角,会近距离观察 → Low 或 Medium
    • 主要道具,玩家会经常互动 → Medium
    • 大量使用的场景物件/远景物体 → High
  2. Read/Write(是否允许 CPU 读写)

    • 勾选:CPU 和 GPU 都可访问网格数据
    • 不勾选:仅 GPU 可访问,上传后释放 CPU 内存

    建议:运行时不需要修改的网格务必取消勾选,许多内存飙升问题就出在忘记关这里

  3. Optimize Mesh(优化网格)

    通过重新组织网格数据,来提高 GPU 的渲染效率
    优化前:就像把一本工具书的页码完全打乱,找每个工具都要翻来翻去
    优化后:就像把书按章节和索引整理好,查找工具时速度飞快

    • Everything (优化所有内容):

      这是最全面、最激进的优化,它会同时优化 Polygon Order(多边形顺序) 和 Vertex Order(顶点顺序)
      通常能带来最好的性能提升,可能会干扰一些依赖于特定顶点顺序的自定义着色器或脚本

    • Polygon Order (优化多边形顺序):

      只优化三角形的绘制顺序,而不改变顶点的内存布局
      当你的脚本或着色器依赖于原始的顶点顺序时(这种情况比较罕见)
      作为一个折中方案,如果 Everything 导致问题,可以回退到此选项试试

    • Vertex Order (优化顶点顺序):

      只优化顶点在内存中的布局顺序,而不改变三角形的绘制顺序

    • None:不优化

    建议:始终勾选 Everything,能提升渲染性能,出现渲染问题时再选择 Polygon Order (优化多边形顺序)

  4. Generate Colliders(生成碰撞体)

    • 勾选:自动生成 MeshCollider
    • 建议:仅在必要时勾选,MeshCollider 性能开销大,简单碰撞用普通几何体Collider

网格压缩决策流程:

  • 重要角色 → Low、Medium Compression
  • 场景道具 → High Compression
  • 永远不需要修改的网格 → 不要勾选 Read/Write
  • 所有静态网格 → 始终选择 Optimize Mesh(优化网格)

顶点数据优化

减少顶点数量和顶点数据量,从源头抓起,在建模时就准备好的事情

  1. 顶点数量控制

    使用 LOD(Level of Detail):根据距离使用不同精度的网格

  2. 顶点数据精简

    移除不必要的顶点属性:

    • 切线:若完全没有法线贴图、各向异性的模型可移除
    • 顶点色:无特殊着色需求的模型可移除
    • 多组 UV:无 光照贴图、细节贴图、流光、特殊采样等效果时可移除第二组 UV
  3. 顶点缓存优化

    为了提升顶点缓存命中率,尽可能让三角形共享顶点
    顶点缓存优化的基础在于良好的建模拓扑(从源头促进顶点共享)
    引擎的 Optimize Mesh(优化网格)选项是在此基础上进行“整理”
    以发挥硬件的最佳性能,但它无法改变模型固有的、低效的拓扑结构

实践配置示例:

  • 高端角色:保留所有顶点数据
  • 场景道具:移除切线、顶点色等
  • 远处物体:使用低模,移除所有额外顶点数据

动画资源导入优化

动画资源是内存和 CPU 的消耗大户

  1. Animation Compression(动画压缩)

    • Off:无压缩,最高精度
    • Keyframe Reduction:减少关键帧数量
    • Optimal:Unity 智能压缩,平衡质量和大小

    建议:角色动画用 Optimal,不重要动画用 Keyframe Reduction

  2. Rotation Error / Position Error / Scale Error

    压缩误差阈值,值越大压缩越狠,质量损失越大

    建议:
    主角核心动作、过场动画,使用 低误差值 (0.1 - 0.5)
    NPC 常规动画,使用 中等误差值 (0.5 - 1.0)
    远景小生物、次要特效,使用 高误差值 (1.0 - 2.0+)

  3. Remove Constant Scale Curves(移除恒定缩放曲线)

    自动检测并移除在整个动画时间段内没有发生变化的缩放曲线
    可以减小动画文件体积和运行时内存占用,降低CPU开销

    工作原理:
    一个角色动画中,大部分骨骼可能只有旋转和位移变化,而缩放始终是 (1,1,1)
    这条不变的缩放曲线会一直被计算和存储
    勾选此选项后,Unity 会在导入时删除这些冗余的恒定曲线

动画系统运行时优化

  1. Animator​ 的 Culling Mode(动画器剔除模式)

    • Always Animate:始终更新,即使不可见(性能最差)
    • Cull Update Transforms:不可见时停止根 Motion 更新
    • Cull Completely:不可见时完全停止动画(推荐)
  2. 动画控制器动画层数优化

    减少活跃的 Animator Layer 数量,按需启用/禁用动画层

  3. 动画事件优化

    避免在每帧触发的事件中执行昂贵操作,使用缓存,避免在事件中频繁查找组件

  4. Humanoid vs Generic 动画类型

    • Humanoid:人形动画,支持重定向,占用更多内存
    • Generic:通用动画,更轻量,不支持重定向

    选择:仅人形角色用 Humanoid,其他用 Generic

更多优化技巧

  1. GPU Skinning(GPU 蒙皮)

    开启:将蒙皮计算从 CPU 转移到 GPU
    Project Settings —> Other Settings -> Rendering -> GPU Skinning

    • CPU:在 CPU 上计算顶点变换
    • GPU:在 GPU 上计算顶点变换
    • GPU(Batched):在 GPU 上计算顶点变换,并合批优化

    优点:大幅减少 CPU 开销
    要求:Shader 支持,现代 GPU

  2. 动画简单化

    对非关键角色使用简单动画(旋转、位移)而非骨骼动画

  3. 对象池 + 动画状态复用

    对频繁创建销毁的动画对象使用对象池
    复用 Animator Controller,通过参数控制不同状态

  4. 动画 LOD 系统

    根据距离使用不同更新频率
    比如通过脚本控制 Animator 的 API 调整更新模式和更新频率

    • 远处角色:降低动画更新频率(如 30 fps → 15 fps)
    • 不可见角色:完全停止动画更新
  5. 蒙皮网格渲染器优化

    减少骨骼数量:人形角色 <= 30根,非人形角色尽可能少

    使用 Enable GPU Instancing:对相同网格的多个实例进行合批

性能分析与监控

  1. 分析工具使用

    • Profiler > Rendering:查看顶点数量、SetPass Calls
    • Profiler > CPU Usage > Animation:监控动画系统CPU开销
    • Frame Debugger:分析每帧的绘制调用
    • Memory: Mesh / AnimationClip
  2. 关键性能指标

    • 顶点数量:每帧 < 100K(移动端),< 500K(PC端)
    • 骨骼数量:单个角色 < 30根(移动端),< 100根(PC端)
    • 动画内存:监控 AnimationClip 内存占用
    • SkinnedMeshRenderer 数量:活跃蒙皮网格数量
  3. 内存优化

    使用 Addressables​ 管理动画资源,及时卸载未使用的 AnimationClip
    监控 Mesh 内存占用,确保 Read/Write 关闭