Unity之图形渲染优化、渲染管线优化、图形性能优化

2015年08月17日 12:04 0 点赞 0 评论 更新于 2025-11-21 18:48

主要内容也可参考:Optimizing Graphics Performance

最简单的优化建议

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

1. 为什么需要针对CPU(中央处理器)与GPU(图形处理器)优化?

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

2. CPU与GPU的限制

GPU限制

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

CPU限制

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

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

3. 关于顶点数量和顶点计算

顶点数量限制

CPU和GPU对顶点的计算处理量都较大。GPU中渲染的顶点数取决于GPU性能和Shader的复杂程度,一般来说,每帧之内,PC上几百万顶点内,移动平台上不超过10万顶点。

顶点计算类型

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

【具体顶点数量和Draw Calls数值应根据项目需求而定。假设项目是3D游戏,需要兼容低配置硬件、保证流畅运行并控制硬件发热,同时达到一定效果(如LIGHTMAP + 雾效),那么顶点数不宜过高。此时,同屏2万顶点是比较合适的数目,Draw Call最好低于70。此外,控制发热需要控制最高帧率,实际上,要保证流畅,帧率不需要太高。】

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

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

假设用上千个三角形模型代替一个上千三角面的模型,在GPU上的开销相近,但在CPU上的消耗会大幅增加。为了减少CPU的工作量,需要减少可见物的数目,具体方法如下:

模型合并

可以手动在模型编辑器中合并相近的模型,或者使用Unity的Draw call批处理(Draw call batching)达到相同效果。具体方法和注意事项可查看:[Draw call batching](http://docs.unity3d.com/Document ... awCallBatching.html)

材质处理

在项目中尽量使用更少的材质,例如将几个分开的贴图合成一个较大的图集。如果需要通过脚本控制单个材质属性,要注意改变Renderer.material会造成一份材质的拷贝,应使用Renderer.sharedMaterial来保证材质的共享状态。有一个合并模型材质的不错插件叫Mesh Baker,可以考虑尝试。

渲染步骤简化

尽量减少一些渲染步骤,如reflections、shadows、per - pixel light等。

材质共享

Draw call batching合并物体时,每个合并后的物体至少应有几百个三角面。如果合并的两个物体不共享材质,不会有性能提升,多材质的物体相当于两个物体使用不同的贴图。因此,为了提升CPU性能,应确保这些物体使用同样的贴图。另外,使用灯光会取消(break)引擎的DRAW CALL BATCH,具体原因可查看:Forward Rendering Path Details

剔除操作

使用相关剔除技术直接减少Draw Call数量,后文会有相关介绍。

5. 优化几何模型

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

三角面控制

避免有不必要的三角面,减少模型的复杂度。

UV贴图优化

UV贴图中的接缝和硬边越少越好,以提高纹理映射的质量。

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

6. 关于光照

若不使用光,渲染速度肯定最快。对于移动端优化,可以采用光照贴图(Lightmapping)来烘培一个静态的贴图,以代替每次的光照计算。在Unity中,生成光照贴图所需时间非常短。这种方法能大大提高效率,并且有更好的表现效果(如平滑过渡处理和附加阴影等)。

在移动设备和低端电脑上,尽量避免在场景中使用真光,而采用光照贴图。这样可以大大节省CPU和GPU的计算量,使CPU的Draw Call减少,GPU需要处理的顶点和像素栅格化工作也相应减少。关于Lightmapping的介绍可参考:Lightmapping

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

图片压缩(Compressed Textures)

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

曾在Unity会议上听说,贴图尽量使用统一大小的格式(如512 512 , 1024 1024),这样在内存中能更好地排序,减少内存空隙,但该说法尚未经过测试。

多重纹理格式(MIPMAPS)

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

8. 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

9. 关于Realtime Shadows(实时阴影)

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

10. 对GPU优化:采用高效的shader

内置Shader选择

有些内置(built - in)Shader有mobile版本,这些版本能大大提高顶点处理性能,但也存在一些限制。

复杂操作符使用

自己编写Shader时,要注意复杂操作符的计算,如pow、exp、log、cos、sin、tan等,这些计算非常耗时,每个像素点的计算中最多使用一次。不建议自己编写normalize、dot、inversesqart操作符,内置的操作符效率更高。

Alpha测试优化

需要注意的是,alpha test非常耗时,应尽量避免使用。

浮点类型选择

浮点类型运算中,精度越低的浮点计算速度越快。在CG/HLSL中:

  • float:32位浮点格式,适合顶点变换运算,但速度较慢。
  • half:16位浮点格式,适合贴图和UV坐标计算,计算速度是highp类型的两倍。
  • fixed:10位浮点格式,适合颜色、光照等计算,计算速度是highp格式的四倍。

关于Shader优化的小提示可参考:Shader Performance

11. 另外的相关优化

Draw Call Batching优化

可参考:Draw Call Batching

渲染统计窗口说明

关于Rendering Statistics Window的说明和提示可参考:Rendering Statistics

角色模型优化

角色模型优化建议如下:

  • 采用单个蒙皮渲染。
  • 尽量少用材质。
  • 少用骨骼节点。
  • 移动设备上角色多边形保持在300 - 1500内(具体根据需求而定)。
  • PC平台上角色多边形保持在1500 - 4000内(具体根据需求而定)。

相关介绍可参考:Modeling Optimized Characters

作者信息

洞悉

洞悉

共发布了 3994 篇文章