文章

UnityShade入门精要(12·性能优化)

性能优化

影响性能的因素有如下几点:

1734933133577

对应的性能优化技术:

1734933200521

性能分析工具

统计窗口:Game 视图右上方的Stats 按钮,它包括了3个方面的统计信息:音频( Audio)、图像 (Graphics) 和网络 (Network),其中图像方面包含

性能分析器:Window->Analysis-> Profiler ,在这里可以看到更详细的数据,比如drawCall统计

帧调试器 : Window->Analysis-> Frame Debugger,运行游戏,点击enable,可以查看每帧的每个渲染事件(最上方显示的int数字和滑动条,和左下方的一个个事件)的渲染结果,包括clear,drawcall 等,右侧是detail详细信息

减少drawcall数目

批处理

每次调用draw call,都是CPU通知GPU执行一次完整渲染流水线的过程,每次走一遍完整的渲染流程都很耗时,因此要避免调用draw call

例如,渲染一千个单独的三角形网格(一千次draw call) 所花费的时间要远远大于 渲染一个包含了一千个三角形的网格(一次draw call)

批处理 (batching) 的目的就是减少draw call的调用,让一次调用尽可能渲染多个物体,把相同材质的物体的顶点数据合并在一起,再一起发送给GPU,作为一次批处理

Unity 中支待两种批处理方式:

一种是动态批处理

一切处理都是 Unity 自动完成的,不需要我们自己做任何操作,而且物体是可以移动的(每帧时Unity都会重新合并一次网格),但缺点是,限制很多,可能一不小心就会破坏了这种机制,导致Unity 无法动态批处理

但是可以自动批处理不仅要材质相同,并且要满足如下条件:

1734934516240

可以从统计窗口直接看到batches的数目,动态批处理的限制条件比较多,很多时候动态批处理都会失效,因此要使用静态批处理

另一种是静态批处理

自由度很高,限制很少;但缺点是可能会占用更多的内存(在VBO中,如果有一千个批处理物体,就会复制一千份网格,内存换取性能),而且经过静态批处理后的所有物体都不可以再移动了(只在运行开始阶段合并一次网格)

只福要把物体面板上的 Static 复选框勾选上即可,并且在运行程序后,才会出现变化

除了forwardbase的pass,其余的也都不会执行静态批处理

可以在性能分析器上看到VBO(顶点缓冲,存储顶点数据)的占用内存

共享材质

如果能让更多的物体有相同的材质,就可以批处理,减少drawcall了

如果两个材质之间只有使用的纹理不同,我们可以把这些纹理合并到一张更大的纹理中,再使用不同的采样坐标对纹理采样即可

如果不同的物体在材质上还有一些微小的参数变化(例如,颜色不同某些浮点屈性不同),一种常用的方法就是使用网格的顶点数据(而非uniform)来存储这些参数

减少需要处理的顶点数目

优化几何体

在建模时,尽可能减少模型中三角面片的数目,

在 Unity 的渲染统计窗口中,显示的数目往往要多千建模软件里显示的顶点数,因为Unity是站在GPU的角度上去计算,为了分离纹理坐标 (uv splits),如果一个顶点的纹理坐标有多个,对于GPU来说,这是不可理解的,因此,它必须把这个顶点拆分成多个具有不同纹理坐标的顶点,还有一种原因为了产生平滑的边界

模型的 LOO(Level of Detail) 技术

我们需要为同 个对象准备多个包含不同细节程度的模型,然后把它们赋给LODGroup组件中的不同等级,Unity 就会自动判断当前位置上需要使用哪个等级的模型

遮挡剔除技术

遮挡剔除可以用来消除那些在其他物件后面看不到的物件, 这意味省资源不会浪费在计算那些看不到的顶点上

减少需要处理的片元数目

控制绘制顺序

从前往后绘制的, 那么就可以很大程度上减少overdraw(同一个像素被绘制了多次)

警惕透明物体

这些物体总是从后往前绘制的,因此一定会造成overdraw

对于透明度混合:不会执行深度测试,因此每一个透明物体都会被完整的渲染一遍

对于透明度测试:虽然没有关闭深度测试,但是由于discard函数是在片元着色器中执行的,也就无法在片元着色器前判断哪些瓦片被真正渲染的,因此会导致延迟渲染技术失效(它的目的就是减少overdraw)

减少实时光照和阴影

当不会执行批处理时,那么draw call的次数就是 :物体 * 每个物体的pass 次

游戏(注重性能)往往使用了烘焙技术,把光照提前烘焙到一张光照纹理 Oightmap) 中,避免实时光照

节省带宽

减少纹理大小

最好长宽值并是2的整数幕,因为有很多优化只有在这种时候才可以发挥最大效用

还可以使用mipmap,多级渐远纹理,它会生成像金字塔的纹理(大小),越小分辨率越低

纹理压缩

利用分辨率缩放

直接调用 Screen.SetResolution设置屏幕分辨率

减少计算复杂度

Shader 的 LOO 技术

Shader 同样有LOD技术,只有Shader 的 LOO值小千某个设定的值,这个 Shader才会被使用

代码方面的优化

尽量使用低精度的变量

慎用分支和循环语句,因为它们在GPU上的实现和在 CPU 上有很大的不同

本文由作者按照 CC BY 4.0 进行授权
本页总访问量