【求知探新】Unity中ShaderLab内存优化

简介:

一、问题描述

请输入图片描述
从上图(进入战斗场景时的内存快照)可以看出,ShaderLab占用居然达到42MB,为什么Shader的占用那么高呢?


二、问题分析

请输入图片描述
由于当前项(ShaderLab)没有说明详细的Shader占用信息。所以只能去另外找原因了,还好,在内存快照的Assets下的Shader项中,有详细的使用信息。

然后我们看到Standard的Shader使用,但项目里面根本没有地方使用过Standard这个Shader,为什么会存在呢?

为此,我们进行了一轮的排查,把部分使用到Standard的地方清除掉,测试并再拿一次内存快照。
请输入图片描述
清除了一部分后,ShaderLab降到27.6 MB(后来完全清除掉Standard,降到21 MB)。果然,主要原因就出在了Standard上。那么问题又来了,为什么我们没有使用到Standard,却会在内存中看到Standard的使用呢?
这里就要说下两个坑了,同样,也是排查这个问题的方法。


三、问题排查

1、模型导入导致

模型导入的时候,“Import Materials”是默认勾选的。所以当模型导入时,Unity会在同目录创建“Materials”目录,并创建相应的材质,而这个材质默认是使用Standard。

由于美术在制作过程中对Prefab中对模型另外赋予材质,所以实际上,默认创建的材质(Standard)是没有使用到的。可是当加载模型的时候,却又把默认创建的材质加载上了,并对着色器解析了,因此导致内存中有Standard。

那么解决方法也很简单,把“Import Materials”去掉,并把没有使用的默认材质删除。

请输入图片描述

注意:如果不把“Import Materials”去掉,导入到其他项目时,材质又会自动创建了。

补充:
由于实际项目中,Prefab改动次数比较大,相应的模型文件改动比较少,所以把项目中的模型和对应的Prefab分开打包成不同的AssetBundle,然后就会出现一个很奇怪的情况。

没有勾选“Import Materials”的模型文件,在实例化Prefab时,ShaderLab会存在一份“Standard”的Shader内存,而这个Shader的引用是指向一个“Default-Material”文件(可是这文件并不存在)。
请输入图片描述
但是,在模型和Prefab在相同的AssetBundle中,或者使用Resources加载时,却不会有“Standard”和“Default-Material”的出现。暂时还不确定是否是Unity 5.3.3版本的Bug,还是Unity的特殊机制。

相关问题参考:https://answer.uwa4d.com/question/595377a5d516f3253948b0d1

临时解决方案:在需要模型与Prefab分开打包时,勾选“Import Materials”,直接使用和修改默认生成的材质。

2、默认模型(Cube、Sphere)创建导致
早期场景搭建时,为了方便定位和可视化,曾经使用Cube等系统默认的Mesh作为锚点,然后在启动游戏时禁用掉。由于这些Cube不启用,性能消耗很轻微,所以就没有理会了。

可是,就因为是系统默认的Mesh,所以创建时,赋予的材质就是默认的材质“Default-Material”,而这个材质使用的着色器就恰恰是“Standard”。所以“Standard”存在的并不冤了。
请输入图片描述

解决的方案也很简单,删掉这些Mesh或者是替换材质。这样,这部分占用的“Standard”就不存在了。


四、总结

由于Standard的变体太多了,所以当引用了Standard的时候,往往会存在多个Standard变体,占用大量的内存。如果,你发觉你的ShaderLab的内存过大,而又那么也不妨找找是不是上述的原因。

那ShaderLab占用内存过大是不是完全是Standard的原因呢?其实并不止的。像我们优化完之后的27MB(完全清除后是21MB),肯定还有其他原因造成的。可是,优化的过程是砍大头,像上文那样,稍微优化一下,就能拿掉20多MB,当然要立刻做,可是越往小的时候,优化效率就越来越低了,所以这时候就需要转移目标看一下“Assets”“Texture2D”这些大头了。所以,剩下ShaderLab的优化方向可能会在以后遇到的时候再补充。

PS:以上内容均在真机上测试






原文出处:侑虎科技
本文作者:admin
转载请与作者联系,同时请务必标明文章原始出处和原文链接及本声明。

目录
相关文章
|
5月前
|
存储 设计模式 监控
运用Unity Profiler定位内存泄漏并实施对象池管理优化内存使用
【7月更文第10天】在Unity游戏开发中,内存管理是至关重要的一个环节。内存泄漏不仅会导致游戏运行缓慢、卡顿,严重时甚至会引发崩溃。Unity Profiler作为一个强大的性能分析工具,能够帮助开发者深入理解应用程序的内存使用情况,从而定位并解决内存泄漏问题。同时,通过实施对象池管理策略,可以显著优化内存使用,提高游戏性能。本文将结合代码示例,详细介绍如何利用Unity Profiler定位内存泄漏,并实施对象池来优化内存使用。
304 0
|
4月前
|
存储 Java 图形学
UNITY性能优化☀️一、GC介绍与Unity内存管理方法
UNITY性能优化☀️一、GC介绍与Unity内存管理方法
|
开发框架 Java .NET
《unity游戏优化》第8章内存优化
《unity游戏优化》第8章内存优化
|
开发框架 Java .NET
《unity游戏优化》第8章内存优化
《unity游戏优化》第8章内存优化
|
Java 图形学
Unity打包符号表 使用ndk addr2line.exe+符号表 将崩溃内存地址解析成函数名
符号表的路径,符号表发布出来的时候是一个zip文件要把它解压出来,里面会有两个文件:arm64-v8a(64位)、armeabi-v7a(32位)不过unity默认打包出来的都是64位的程序,所以这个前面加上你的真实路径+arm64-v8a\libil2cpp.sym.so就可以了。
|
图形学
Unity 优化之 移动游戏加载性能和内存管理全解析【2017年版】
首先感谢UWA的公开课讲解,本文中的内容主要采集于UWA2017的公开课公开课中的优化点对于项目的帮助是不容小觑的~ 去年的PPT截取,笔者抽时间整理一下,有相关视频的PPT的截图和博客地址。
1192 0
|
缓存 机器人 测试技术