Unity3D降低性能方法

目录

一、烘焙灯光

当出现CPU bound(CPU超负荷导致卡顿)时,我们可以通过减少不必要的细节物体、利用摄像机远剪辑面减少呈现的物体、遮挡剔除以及LOD等技术来解决该问题。原因是减少了CPU向GPU发送指令的次数。

二、静态批处理

三、减少不必要的细节物体

四、利用摄像机远剪辑平面减少呈现的物体(视椎体剔除)

五、遮挡剔除(有问题)

六、LOD Group

七、自定义遮挡剔除

八、Skinned meshes

九、尽量避免在主线程上(Unity生命周期方法)处理非渲染任务

CPU bound 总结:

GPU bound 总结:

代码实现静态批处理

GPU Instancing


一、烘焙灯光

      选中灯光物体,在Light组件中设置Mode参数为Baked,然后点击Window-Lighting-Settings,在Lighting面板中点击最下方的Generate Lighting按钮即可实现烘焙。烘焙是为了使Unity无须实时为灯光做工作而优化的一种方法,相当于给周围环境贴上一张灯光效果的贴图。这样就能够提升FPS,减少阴影数量Shadow caster.

当出现CPU bound(CPU超负荷导致卡顿)时,我们可以通过减少不必要的细节物体、利用摄像机远剪辑面减少呈现的物体、遮挡剔除以及LOD等技术来解决该问题。原因是减少了CPU向GPU发送指令的次数。

二、静态批处理

    选中要进行批处理渲染的物体,在Inspector面板的Static下拉列表,打开后选中Batching Static,然后检查Edit->Player Settings->Player->Static Batching打√,还有一个是Dynamic Batching动态批处理,这个最好也勾上。

    运行游戏后,可以打开Window->Profiler->Rendering 检查Draw Calls是否减少了,减少了就说明优化了。完全没有静态批处理的物体的话,物体渲染工作全部交给动态批处理来完成,动态批处理是Unity自己做的工作,不用我们管,而且基本是一个渲染处理一个Calls的模式,这样会导致CPU空闲,GPU忙碌,从而产生CPU等待GPU这段空闲时间,产生了所谓的“卡顿”现象,也叫“失帧”,在直观理解是FPS会降低。(FPS越低越不好)

 静态批处理是消耗内存来达到减少DC的,在手游可能会不常用。

三、减少不必要的细节物体

在复杂场景中,最简单减少DC的方法就是直接删除影响不是很大的细小物体。

四、利用摄像机远剪辑平面减少呈现的物体(视椎体剔除)

我们可以通过调整Clipping Planes的Far数值(从摄像机到远剪辑平面的距离),适当地调小Far,并用Fog雾来掩饰远处物体的隐藏即可。

五、遮挡剔除(有问题)

    遮挡剔除也叫遮挡视图:当摄像机在Occlusion范围内,会将摄像机可视范围之外的物体不进行渲染 以及 在一个大物体后面的物体也不会进行渲染,即不可视物体将不会进行渲染。

  将要遮挡的物体全部选中,然后选择Occluder Static之后,在Window->Occlusion Culling-Bake,Bake之后选择摄像机图标,然后场景中只有这个摄像机可以看到的物体会被渲染出来。物体越多越有效,注意摄像机进入黄色区域才会产生遮挡剔除。

但是经测试只在这种模式下才会产生作用,如下图:

(选中Occlusion的Visualization进入Occlusion模式)

在运行时,不会产生任何作用(Unity 2017.1.1f1版本),进入Frame Debug编辑器观察详细渲染帧情况,与不使用遮挡剔除的情况一致,也就是说遮挡剔除并没有生效。

六、LOD Group

给一个空物体加上一个LOD Group组件

在LOG Group上有4个颜色,绿色 紫色 蓝色 红色

在每种颜色上都设置一个模型Prefab,绿色最精细的模型,红色是最粗糙的模型。(红色一般都不用设置了因为看不到)

可以设置每个颜色区域的百分比。

这个LOG Group可以让摄像机看到的物体根据距离改变物体的不同形态,例如:精细形态、一般形态、粗糙形态,我们在离物体近的时候,就显示精细形态,所以绿色放一个精细的预制体,离物体越远就不用摆放那么精细了。这样来优化性能。

这个需要美工配合的,也就是说一个物品需要做出以上四种形态。

七、自定义遮挡剔除

用自定义脚本来禁用掉在视野之外的物体,特别是带Renderer的物体。

八、Skinned meshes

SkinnedMeshRenderers用于通过使用一种称为骨骼动画的技术对网格进行变形来实现动画。渲染蒙皮网格可能是一个昂贵的操作。如果我们可以在Profiler窗口中看到渲染皮肤网格会导致游戏CPU受限,我们可以尝试做以下几件事来提高性能:

  • 例如,我们可能导入了一个使用SkinnedMeshRenderer组件的模型,但实际上我们并没有对其进行动画处理。在这种情况下,用MeshRenderer组件替换SkinnedMeshRenderer组件将有助于提高性能。
  • 在模型网格中使用更少的顶点可以减少必须完成的工作量。
  • 在某些平台上,剥皮可以由GPU而不是CPU来处理。如果我们在GPU上有很多容量,这个选项可能值得尝试。我们可以在Playing Settings - Others 设置中为当前平台和质量目标启用GPU剥皮。

九、尽量避免在主线程上(Unity生命周期方法)处理非渲染任务

假设:主线程上需要渲染100个物体,同时还要处理一些与渲染无关的事情,可以将与渲染无关的事情如计算数据,放到非主线程处理,尽可能地减少主线程的负荷,从而避免CPU bound。

CPU bound 总结:

CPU bound 是指 在一次渲染中,CPU拖了GPU的后腿,CPU频繁地向GPU发送命令,产生大量的SetPass调用(DC),导致CPU超负荷,造成游戏卡顿、失帧(原因:GPU空闲),一个不卡的游戏,其CPU和GPU的工作是双方都很流畅地工作的。

为了减少SetPass调用,可通过如下三种方法:

① 可以减少渲染的物体数量

可参考上面的三、四、五、六、七章节介绍

② 减少每个物体照明、阴影、反射渲染的次数

可参考上面的第一章节介绍,烘焙阴影、反射探针等技术来减少,即多采用静态的东西,而不是实时动态的。

③ 使用批处理 和 合并物体Mesh减少批处理次数

可参考上面的第二章静态批处理介绍,合并物体Mesh可以看本人博客文章 有介绍

④ 使用图集减少DC

 Unity3D-UGUI图集打包与动态使用(TexturePacker)_CJsen的博客-CSDN博客_texturepacker unity

GPU bound 总结:

GPU bound :在一次渲染中,GPU拖了CPU后腿,一般是GPU(渲染管线)处理大量的数据不够迅速导致。

① Fill rate 填充率

填充率是指GPU每秒可以渲染到屏幕上的像素数。如果我们的游戏受填充率的限制,这意味着我们的游戏试图绘制更多的像素每帧GPU无法处理。

检查是否是GPU填充率过低导致GPU bound的,可以通过将Game窗口的分辨率调低,再次进行性能测试得知,若有明显改观,可能是Fill rate问题。

可通过优化着色器(shader)来减少游戏每帧所需绘制的像素数量,例如:本身使用的是内置着色器,可用带"mobile"的着色器进行替代 或 其他合适的着色器进行替代,只要确保在视觉保真度基本不变的情况就可以适当地选取合适的着色器,进行减少游戏所要求渲染的像素数量。

若是自定义着色器,则需要专业的shader人员进行优化片元着色器fragment。

② Overdraw 重复绘制

Overdraw是指同一个像素被多次绘制,当物体与物体重叠时会发生,如:UI重叠、为着色的颗粒、透明材料。

③ Image Effects 图像效果(这个有点懵逼)

使用图像效果可以大大提高填充率问题,特别是如果我们使用多个图像效果。如果我们的游戏使用了图像效果,并且正在与填充率问题作斗争,我们可能希望尝试不同的设置或更优化的图像效果版本(如Bloom(优化)代替Bloom)。如果我们的游戏在同一个相机上使用多个图像效果,这将导致多个着色器通过。在这种情况下,将图像效果的着色器代码合并到一个单一的通道中可能是有益的,例如在Unity的后处理堆栈中。如果我们优化了图像效果,但仍然存在填充率问题,我们可能需要考虑禁用图像效果,特别是在低端设备上。

相关参考文献:英文-官方文档说明(比较详细)

代码实现静态批处理

PS:这个不能超过65000个顶点,需要自己处理

public static void Combine(GameObject[] gos, GameObject staticBatchRoot);

将staticBatchRoot下的子物体们gos用静态批处理的方式进行优化处理,减少Batch次数。
重要提示:只有具有相同材质的对象才可以批量处理,因此尽可能多地共享纹理/材质是很有用的。

staticBatchRoot可移动,其子物体们不可移动

第一个参数gos是staticBatchRoot下的子物体GameObject数组

GPU Instancing

可使用 SystemInfo.supportsInstancing 进行判断是否支持GPU Instancing,再用代码动态设置材质的GPU Instancing属性

material.enableInstancing = SystemInfo.supportsInstancing;

GPU Instancing相关补充:【Unity】MaterialPropertyBlock(MPB) GPUInstancing SRPBatch个人见解_两水先木示的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值