关于Unity 几种优化建议

2015年03月19日 11:00 0 点赞 0 评论 更新于 2025-11-21 17:39

最简单的优化建议

  1. 顶点数控制:在PC平台,保持场景中显示的顶点数少于200K - 3M;在移动设备上,顶点数应少于10万。不过,具体的顶点数限制取决于目标GPU与CPU的性能。
  2. Shader选择:若使用U3D自带的Shader,在表现效果不差的情况下,优先选择Mobile或Unlit目录下的Shader,它们的效率更高。
  3. 材质共用:尽可能让多个物体共用材质,以减少资源消耗。
  4. 静态物体设置:将不需要移动的物体设为Static,这样引擎可以对其进行批处理,提高渲染效率。
  5. 灯光使用:尽可能减少灯光的使用,尤其是动态灯光,因为灯光会增加CPU和GPU的计算负担。
  6. 贴图格式:尝试使用压缩贴图格式,或者用16位代替32位,可降低内存占用并提高加载速度。
  7. 雾效控制:如果场景不需要雾效(fog),就不要使用,以免增加不必要的计算。
  8. 遮挡剔除:尝试使用Occlusion Culling,在房间过道多、遮挡物体多的场景中非常有用。但使用不当可能会增加CPU的计算负担。
  9. 天空盒应用:使用天空盒来“褪去”远处的物体,减少不必要的渲染。
  10. Shader优化
    • 用贴图混合的方式代替多重通道计算,降低计算复杂度。
    • 注意float/half/fixed的使用,根据不同的计算需求选择合适的浮点类型。
    • 避免在Shader中使用复杂的计算,如pow、sin、cos、tan、log等。
    • 尽量减少Fragment的使用。
  11. 动画脚本检查:注意是否有多余的动画脚本,模型自动导入到U3D时可能会附带动画脚本,大量的动画脚本会严重影响CPU的计算性能。
  12. 碰撞检测优化:注意碰撞体的碰撞层,舍去不必要的碰撞检测,降低CPU的计算负担。

为什么需要针对CPU与GPU优化

CPU和GPU都存在各自的计算和传输瓶颈,而且不同的CPU或GPU性能差异较大。因此,游戏需要针对目标用户的CPU与GPU能力进行针对性开发,以确保游戏在不同设备上都能有良好的性能表现。

CPU与GPU的限制

GPU限制

GPU通常受到填充率(Fillrate)和内存带宽(Memory Bandwidth)的限制。如果游戏在低质量表现下运行速度明显加快,很可能需要限制GPU的填充率。

CPU限制

CPU一般受需要渲染物体的个数限制,CPU向GPU发送渲染物体的命令称为DrawCalls。通常情况下,DrawCalls数量应尽可能控制,在能保证表现效果的前提下越少越好。一般来说,电脑平台上DrawCalls控制在几千个之内,移动平台上控制在几百个之内,但这并非绝对标准,仅作参考。

需要注意的是,渲染(Rendering)本身可能并非性能瓶颈,问题很可能出在脚本代码的效率上。可以使用Profiler进行查看,关于Profiler的介绍可参考:Profiler 。另外,在GPU中显示的RenderTexture.SetActive()占用率很高,这是因为同时打开了编辑窗口,并非U3D的BUG。

顶点数量和顶点计算

GPU顶点计算

GPU中渲染的顶点数取决于GPU性能和SHADER的复杂程度。一般而言,每帧之内,PC上的顶点数应控制在几百万以内,移动平台上不超过10万顶点。

CPU顶点计算

CPU中的计算主要集中在蒙皮骨骼计算、布料模拟、顶点动画、粒子模拟等方面。而GPU则负责各种顶点变换、光照、贴图混合等计算。

具体的顶点数和DrawCall数量应根据项目需求来确定。例如,对于需要兼容低配置硬件、保证流畅运行并控制硬件发热,同时还要达到一定效果(如LIGHTMAP + 雾效)的3D游戏,同屏2W顶点是比较合适的数目,DrawCall最好低于70。此外,为了控制发热,需要控制最高帧率,实际上,要保证游戏流畅,帧率并不需要太高。

针对CPU的优化——减少DRAW CALL的数量

为了将物体渲染到显示器上,CPU需要完成一系列工作,如区分需要渲染的物体、判断物体是否受光照影响、选择合适的SHADER并为其传参、向显示驱动发送绘图命令以及发送删除命令等。

假设用上千个三角形模型代替一个上千三角面的模型,在GPU上的消耗相差不大,但在CPU上的消耗会大幅增加。为了减轻CPU的负担,需要减少可见物的数目,可采取以下方法:

  1. 模型合并:合并相近的模型,可以手动在模型编辑器中进行合并,也可以使用UNITY的Draw call批处理(Draw call batching)达到相同效果。具体方法和注意事项可查看:Draw call batching
  2. 材质处理:在项目中尽量使用更少的材质(material),可以将几个分开的贴图合成一个较大的图集。如果需要通过脚本来控制单个材质属性,应使用Renderer.sharedMaterial来保证材质的共享状态,因为改变Renderer.material会造成一份材质的拷贝。此外,有一个不错的合并模型材质的插件叫Mesh Baker,可以考虑尝试。
  3. 渲染步骤简化:尽量少用一些渲染步骤,如reflections、shadows、per - pixel light等。
  4. 材质共享:Draw call batching合并物体时,每个合并后的物体至少应有几百个三角面。如果合并的两个物体不共享材质,不会有性能上的提升。因此,为了提升CPU的性能,应确保这些物体使用同样的贴图。另外,使用灯光会取消(break)引擎的DRAW CALL BATCH,详情可查看:Forward Rendering Path Details
  5. 剔除优化:使用相关剔除技术直接减少Draw Call数量,后续会有相关介绍。

优化几何模型

优化几何模型有两个基本准则:

  1. 减少不必要的三角面:避免模型中存在不必要的三角面,以降低顶点数和计算量。
  2. 减少UV贴图接缝和硬边:UV贴图中的接缝和硬边越少越好,这样可以提高纹理映射的质量和效率。

需要注意的是,图形硬件实际处理的顶点数与硬件报告的并不相同。模型处理应用通常展示的是几何顶点数量,但在显卡中,一些几何顶点会被分离(split)成两个或更多逻辑顶点用于渲染。如果顶点有法线、UV坐标、顶点色等信息,则该顶点必定会被分离。因此,游戏中实际处理的顶点数量会比几何顶点数量多很多。

关于光照

在不使用光的情况下,渲染速度最快。对于移动端优化,可以采用光照贴图(Lightmapping)来烘焙一个静态的贴图,以代替每次的光照计算。在U3D中,生成光照贴图只需要很短的时间。这种方法不仅能大大提高效率,还能获得更好的表现效果,如平滑过渡处理和附加阴影等。

在移动设备和低端电脑上,尽量不要在场景中使用真光,而应使用光照贴图。这样可以大大节省CPU和GPU的计算资源,使CPU的DrawCall减少,GPU的顶点处理和像素栅格化工作量也相应减少。关于光照贴图的详细信息可查看:Lightmapping

对GPU的优化——图片压缩和多重纹理格式

图片压缩(Compressed Textures)

图片压缩可以降低图片大小,实现更快的加载速度和更小的内存占用。压缩贴图比起未压缩的32位RGBA贴图,占用的内存带宽要少得多。相关信息可查看:Compressed Textures

曾有在U3D会议上提到的优化建议,即贴图尽量使用相同大小的格式(如512 512 、 1024 1024),这样可以使内存排序更优,减少内存空隙,但该建议尚未经过测试验证。

多重纹理格式(MIPMAps)

多重纹理格式的原理与网页上的缩略图类似。在3D游戏中,为游戏的贴图生成多重纹理贴图,远处显示较小的物体使用小的贴图,显示较大的物体使用精细的贴图。这样可以更有效地减少传输给GPU的数据量。相关信息可查看:MIPMAps

LOD、Per - Layer Cull Distances、Occlusion Culling

LOD(Level Of Detail)

LOD是一种常用的3D游戏技术,其功能类似于多重纹理贴图。它根据模型在屏幕中显示大小的比例,判断使用高或低层次的模型,从而减少对GPU的传输数据和GPU所需的顶点计算。相关介绍可查看:Level Of Detail

摄像机分层距离剔除(Per - Layer Cull Distances)

为小物体标识层次,然后根据其与主摄像机的距离判断是否需要显示,以此减少不必要的渲染。相关信息可查看:Per - Layer Cull Distances

遮挡剔除(Occlusion Culling)

当某个物体在摄像机前被另一个物体完全挡住时,不将其发送给GPU进行渲染,从而直接降低Draw Call。但在某些情况下,在CPU中计算物体是否被挡住会消耗大量计算资源,反而得不偿失。相关介绍可查看:Occlusion Culling

关于Realtime Shadows(实时阴影)

实时阴影技术效果很棒,但会消耗大量的计算资源,给GPU和CPU都带来沉重的负担。详细信息可参考:Realtime Shadows

对GPU优化:采用高效的shader

  1. 内置Shader选择:有些内置(built - in)Shader有mobile版本,这些版本能大大提高顶点处理的性能,但也会有一些限制。
  2. 复杂计算优化:自己编写Shader时,要注意避免使用复杂的操作符计算,如pow、exp、log、cos、sin、tan等,每个像素点的计算中最多使用一次。不建议自己编写normalize、dot、inversesqart操作符,因为内置的操作符效率更高。
  3. Alpha测试注意:需要注意的是,alpha test非常耗时,应谨慎使用。
  4. 浮点类型选择:在浮点类型运算中,精度越低的浮点计算速度越快。在CG/HLSL中:
    • float:32位浮点格式,适合顶点变换运算,但计算速度较慢。
    • half:16位浮点格式,适合贴图和UV坐标计算,计算速度是highp类型的两倍。
    • fixed:10位浮点格式,适合颜色、光照等计算,计算速度是highp格式的四倍。

关于Shader优化的小提示可查看:Shader优化提示

另外的相关优化

  1. Draw Call Batching优化:可参考Draw Call Batching优化
  2. Rendering Statistics Window说明:关于Rendering Statistics Window的说明和提示可查看:Rendering Statistics Window
  3. 角色模型优化:角色模型的优化建议包括使用单个蒙皮渲染、尽量少用材质、少用骨骼节点。在移动设备上,角色多边形数量应保持在300 - 1500内;在PC平台上,保持在1500 - 4000内,但具体数量还需根据项目需求确定。相关信息可查看:角色模型优化

作者信息

feifeila

feifeila

共发布了 3994 篇文章