unity 优化学习
性能优化是游戏项目开发过程中一个永恒的话题,项目的性能优化主要围绕CPU,GPU和内存三个方面进行,
影响内存的主要三个部分 1、资源内存占用, 2、引擎模块自身内存的占用, 3、托管堆内存占用, 你的资源和代码质量都会影响内存。
优化方向:1、资源内存, 2 图形和GPU 3、编程和代码框架 4、项目中各种资源组件的配置。
资源内存优化:1、资源压缩 2、资源合并 3、资源卸载 4、资源池化 资源管线可以大幅影响应用程序的性能,资源的内存占用往往占据总体内存的70%以上。 图形和GPU优化:1、Shader优化 2、渲染优化 3、LOD优化 4、剔除优化 5、光照优化 6、阴影优化 7、粒子优化 8、UI优化 9、特效优化 Shader优化:1、Shader代码优化 2、Shader合并 3、Shader精度优化 4、Shader剔除 5、Shader缓存 6、Shader异步加载 7、Shader预编译
正确的导入纹理,纹理会占用大部分内存 减少Max size:使用能生成视觉上课接受的结果的最低设置,这种非破坏性的方式,可以快速降低纹理内存。 使用2的幂次(POT), unity 要求移动端纹理压缩格式(PVRCT 或者 ETC) 采用POT纹理尺寸。 制作纹理图集, 将多个纹理放置到单个纹理中,可以减少绘制调用和加快渲染速度,使用unity 精灵图集或第三方texture packer 可以制作纹理图集。 关闭 read 、write enabled选项,开启此选项,CPU 和gpu 可寻址内存中都会创建副本,纹理会占用双倍内存。 禁用不必要的 mipmap,对于在屏幕中大小保持不变的纹理(如2d精灵和ui图形) mipmap 不是必需的,对于与摄像机的距离会发生变化的3d模型,请保留mip map启用状态。
尽可能减少过度绘制和alpha 混合,避免绘制不必要的透明或者半透明图像,
检查多边形面数,分辨率越高的模型,需要的内存使用量越大,并可能占用更长的GPU时间。 使用细节级别(LOD) 随着对象移动到远处,细节级别可以将它们切换为使用更简单的网格。以及更简单的材质和着色器,从而帮助提高gpu性能。 使用遮挡剔除来移除隐藏的对象,隐藏在其他对象之后的对象仍然可能渲染和使用资源。使用遮挡剔除可以将它们丢弃,摄像机之外的视椎体剔除是自动执行的,遮挡剔除(Occlusion Culling)是要经过烘焙过程,只需将对象标记为静态遮挡物或者被遮挡物,然后通过window- rendering - occlusion culling烘焙遮挡剔除数据,烘焙完成后,unity会自动剔除被遮挡的对象。
CPU 过多的Draw Calls 复杂的脚本或者物理模拟
顶点处理 过多的顶点 过多的逐顶点计算
像素(Fragment)处理 过多的fragment,overdraws 过多的逐像素计算
带宽 尺寸很大且未压缩的纹理 分辨率过高的framebuffer
对于CPU来说,限制它的主要是游戏中的Draw Calls。那么什么是Draw Call呢?如果你学过OpenGL,那么你一定还记得在每次绘图前,我们都需要先准备好顶点数据(位置、法线、颜色、纹理坐标等),然后调用一系列API把它们放到GPU可以访问到的指定位置,最后,我们需要调用_glDraw命令,来告诉GPU如何渲染。而调用_glDraw命令的时候,就是一次Draw Call。那么为什么Draw Call会成为性能瓶颈呢(而且是CPU的瓶颈)?上面说到过,我们想要绘制图像时,就一定需要调用Draw Call。例如,一个场景里有水有树,我们渲染水的时候使用的是一个material以及一个shader,但渲染树的时候就需要一个完全不同的material和shader,那么就需要CPU重新准备顶点数据、重新设置shader,而这种工作实际是非常耗时的。如果场景中,每一个物体都使用不同的material、不同的纹理,那么就会产生太多Draw Call,影响帧率,游戏性能就会下降。其他CPU的性能瓶颈还有物理、布料模拟、粒子模拟等,都是计算量很大的操作。
而对于GPU来说,它负责整个渲染流水线。它会从处理CPU传递过来的模型数据开始,进行Vertex Shader、Fragment Shader等一系列工作,最后输出屏幕上的每个像素。因此它的性能瓶颈可能和需要处理的顶点数目的、屏幕分辨率、显存等因素有关。总体包含了顶点和像素两方面的性能瓶颈。在像素处理中,最常见的性能瓶颈之一是overdraw。Overdraw指的是,我们可能对屏幕上的像素绘制了多次。