首页 > 代码库 > Unity加载模块深度解析(网格篇)

Unity加载模块深度解析(网格篇)

在上一篇 加载模块深度解析(一)中,我们重点讨论了纹理资源的加载性能。这次,我们再来为你揭开其他主流资源的加载效率。

这是侑虎科技第53篇原创文章,欢迎转发分享,未经作者授权请勿转载。同时如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群465082844)


资源加载性能测试代码

与上篇所提出的测试代码一样,我们对于其他资源的加载性能分析同样使用该测试代码。我们将每种资源均制作成一定大小的AssetBundle文件,并逐一通过以下代码在不同设备上进行加载,以期得到不同硬件设备上的资源加载性能比较。
技术分享

测试环境
引擎版本:Unity 5.2版本
测试设备:三台不同档次的移动设备(Android:红米2、红米Note2和三星S6)


网格资源

网格资源与纹理资源一样,在加载时同样会造成较高的CPU占用,且其加载效率由其自身大小(网格数据量)决定。因此,我们通过选择不同数据量的网格资源来详细分析其加载效率。

测试1:不同面片数的网格资源加载效率测试
我们选取了四种不同面片数的网格资源,含有的面片数分别为1K、5K、10K和50K,且不含有Tangent顶点属性。四组网格资源的内存占用分别为195KB、0.8MB、1.4MB和3.9MB,其对应AssetBundle大小为43KB、108KB、178KB和507KB。

测试网格:
技术分享

我们在三种不同档次的机型上加载这些网格资源,为降低偶然性,每台设备上重复进行十次加载操作并将取其平均值作为最终性能开销。具体测试结果如下表所示:

技术分享

通过上述测试,我们可以得到以下结论:

1、资源的数据量对加载性能影响较大,面片数越多,其加载越为耗时。设备性能越差,其耗时差别越为明显;

2、随着硬件设备性能的提升,其加载效率差异越来越不明显。

测试2:相同面片数、不同顶点属性的加载效率测试
我们选择测试1中的网格资源做为该测试的样本数据,并在打包时加入Tangent顶点属性。则四组网格资源的内存占用分别为287KB、1.2MB、2.1MB和5.8MB,其对应AssetBundle大小为72KB、228KB、376KB和937KB。与测试1相同,我们在三种不同档次的机型上重复进行十次加载操作并将取其平均值作为最终性能开销。具体测试结果如下图所示:
技术分享
技术分享
通过上述测试,我们可以得到以下结论:

1、顶点属性的增加对内存和AssetBundle包体大小影响较大。与测试1中未引入Tangent顶点属性的网格数据相比,测试2中的网格数据在内存上均大幅度增加(增加量与网格顶点数有关),且AssetBundle大小同样有成倍(1~2)的增加。

2、顶点属性增加对于加载效率影响较大,且顶点数越多,影响越大。

注意事项:
模型常见的顶点属性主要有Position、UV、Normal、Tangent和Color。Color属性与Tangent属性一样,如果网格顶点拥有该属性,同样会对内存、物理体积和加载性能造成影响。

在使用Draw Call Batching时,切忌将不同属性的网格模型拼合在一起。举个例子 ,100个网格模型进行Static Batching,如果99个模型只有Position和UV两种属性,而剩下1个模型函数有Position、UV、Normal、Tangent和Color五种属性。那么引擎在进行拼合时,会将前99个模型的顶点属性补齐,然后再进行拼合。这样无形中会增加大量的内存占用,从而造成不必要的内存浪费。

测试3:开启/关闭Read/Write功能的加载效率测试
我们使用测试1中的网格资源数据,并关闭其Read/Write功能,从而来查看其Read/Write功能对加载效率的影响。关闭Read/Write功能后,四组网格资源的内存占用分别为104KB、454KB、0.8MB和2.3MB,其对应AssetBundle大小为38KB、94KB、152KB和428KB。与测试1相同,我们在三种不同档次的机型上重复进行十次加载操作并将取其平均值作为最终性能开销。具体测试结果如下图所示:
技术分享
技术分享

通过上述测试,我们可以得到以下结论:

1、关闭Read/Write功能会降低AssetBundle的物理大小,其降低量与资源本身数据量相关。同时,关闭Read/Write功能会大幅度降低网格资源的内存占用;

2、关闭Read/Write功能会略微提升该资源的加载效率。


通过以上测试和分析,我们对于网格资源的管理建议如下:

1、在保证视觉效果的前提下,尽可能采用“够用就好”的原则,即降低网格资源的顶点数量和面片数量;

2、研发团队对于顶点属性的使用需谨慎处理。通过以上分析可以看出,顶点属性越多,则内存占用越高,加载时间越长;

3、如果在项目运行过程中对网格资源数据不进行读写操作(比如Morphing动画等),那么建议将Read/Write功能关闭,既可以提升加载效率,又可以大幅度降低内存占用。

正是由于以上加载效率问题,UWA对每个网格资源参数进行了详细的分析。通过性能测评和资源检测两个工具,对项目在Online运行和Offline制作阶段进行双重检测,从而方便加快速查看资源的使用情况,定位引发性能问题的具体资源。

针对网格顶点数据的检测,可以通过以下两种方式:
1. 通过性能测评报告查看:
技术分享

2. 通过资源检测报告查看:
技术分享

针对网格顶点属性的检测,可通过性能测评报告进行查看:
技术分享

针对网格顶点Read/Write功能的检测,可通过资源检测报告进行查看:
技术分享

说明:以上测试数据为我们所用的测试网格加载数据,需要指出的是,不同网格资源的加载效率会略有相同,因为其数值的不同会造成AssetBundle压缩包大小的不同,进而造成最终加载效率的不同。同时,需要注意的是,加载方式的不同(一个协程逐资源加载/多协程同时加载),其加载效率也是完全不同的。关于这一点,我们将在后续文章中进行讨论。最后,我们后续会进行更多的测试,以期为大家提供更为普遍的测试结果。

以上为网格资源在加载时的性能测试。关于加载模块的性能问题,我们会不断推出Shader、音频等其他资源的加载性能分析、资源卸载性能分析、资源实例化性能分析、不同加载方式的性能分析等一系列技术文章,并对目前UWA所检测过项目的共性问题进行总结,以期让大家对项目的加载效率有更加深入的认知,并提升对加载模块的掌控能力。

Unity加载模块深度解析(网格篇)