性能优化(21)——Unity中的Simplization

  1. 1. Unity中的简化
  2. 2. 以URP为例,如何在Unity下做Simplization
  3. 3. Unity下的简化手段(比较常用的手段)
  4. 4. 用户也可以通过脚本或插件做一些自定义的简化操作

Unity中的简化

  • Simplization就像桃子分类,将不同的桃子按不同品质大小分类装箱,以满足不同桃子产品的需求
  • 类比到性能优化中,就是将各类资源、功能分类简化,以满足不同平台、不同设备、不同类型的产品需要

以URP为例,如何在Unity下做Simplization

  • 哪些是需要简化的内容
  • 广义上将:
    • 运行效率较重的资源。如运行时内存占用较高,或处理耗时较长的资源
    • 低效、不合适功能。某些低端设备或平台不能一味地去堆砌功能,更应该去考虑平台的兼容性和此功能的通用性,做到最好的性价比
  • 这里的简化操作不能简单地理解为重新制作资源,应当理解成是基于现有的资源进行简化操作
  • 通常情况下,我们最常用的简化手段就是分级配置,各种LOD结合一些场景数据结构做简化。当然还有一些替代体的方案

Unity下的简化手段(比较常用的手段)

  • Quality Settings:通过这个设置,你可以自定义在不同平台、设备下,Unity现有的一些功能的设置分级。你可以预先设置在哪些平台下开启或不开启某些功能,包括分辨率、贴图分辨率、阴影质量等的一系列设置
  • 通过烘焙光照简化实时光照:在静态灯光场景下,可以使用烘焙的方案替代实时光照方案
  • 通过BoundingBox或替代体碰撞代替Mesh碰撞
  • 用Local Volume代替Global Volume来做特效与后效的区分
  • 用多条RayCast射线检测方式代替开销比较高的SphereCast、CapsuleCast等
  • 用纹理字体代替系统文字
  • Mesh LOD:根据距离采用不同复杂度级别的Mesh进行渲染,以达到不影响视觉表现,同时带来更小的开销
  • Shader LOD:来做多平台或低端设备上的兼容性,尤其是一些Shader效果需要图形API版本要求时
  • HLOD:是Unity针对于大世界提出的一种简化方案。它可以在长视距下用单个静态网格组合替代多个静态网格对象,有助于减少场景渲染对象的个数,同时减少DrawCall调用次数来做场景渲染优化。这个方案会有一定的CPU与内存开销,要看具体项目类型测试后采用。Unity将例子与库都放在官方GitHub上了
  • 通过Camera Override代替URP管线中的一些通用设置:避免了在管线中创建一些长时间无用的渲染资源,比如Copy Depth、Copy Color等这些创建的RP资源
  • 各种OnDemand更新或分级设置接口:如OnDemandRendring

用户也可以通过脚本或插件做一些自定义的简化操作

  • 场景简化数据结构:如上一章Culling中提到过的场景数据结构,这类结构不仅可用作Culling,还可以做Simplization与Batching。其中如果是PC端做ReTracing的话,一定要用到场景数据结构来简化,要不纯像素的话,效率上根本达不到实时渲染。此外,SDF体素化、点云等都是做简化渲染的重要手段
  • 第三方LOD方案:如Automatic LOD、Poly Few|Mesh Simplifier and Auto LOD Generator、Mesh Simplify、Amplify Impostors等,在资源商店搜索LOD或Simplify可以找到很多插件
  • Mesh Impostor
  • Animation LOD:不光模型,动画方面也可以尝试做LOD。比如做动画频率的LOD,可以根据视距降低远处角色的动画频率,或使用骨骼LOD为远距角色采用另一套骨骼较少的骨骼框架
  • 2D寻路代替Navigation Mesh
  • 扩展类似OnDemand接口:实现按需创建或按需更新的逻辑,对于一些复杂的游戏资源或逻辑也是非常必要的

  • 总之除了利用好Unity本身的Simplization操作功能外,我们在写功能时也要有多级可配置简化的思想,这样会让你最后优化产品时,不至于由于无法简化而不得不更换方案或重新开发