贴图资源管理功能主要用于解决游戏项目中贴图资源使用不合理、资源包贴图资源冗余等问题导致的内存消耗。目标是通过单独的资源管理模块实现对游戏项目中贴图资源的全生命周期管理。
主要功能:
Texture Manager可以通过Player Setting 中 Texture manager setting 控制开关。其核心主要将贴图资源从assetbundles中抽离,在单独的模块进行管理,其中assetbundles只保留贴图的元数据信息。通过Texture Manager可以有效的帮助解决游戏项目中纹理资源使用不合理、资源包纹理资源冗余等原因导致的显存和内存消耗问题;并且可以有效解决多平台格式问题。
Key features:
增加了纹理纹理重映射功能,降低Texture冗余导致的显存消耗;
增加了贴图多格式支持功能,同一套AssetBundle可以支持多套纹理(每套纹理针对不同平台使用不同的压缩格式;
增加了显存预算功能,可以根据预设内存预算动态剔除不必要的贴图资源显存内存占用;
增加了对贴图资源的lazy upload,将场景贴图上传延迟到根据场景中实际需要按需上传;
基于indexedDB,增加了对贴图资源文件的缓存管理,降低文件占用内存消耗(微信平台默认使用宿主资源管理);
Known limits:
目前功能暂不支持 unity spritealtas, 仅支持原生美术制作的图集(Tuanjie 1.1.2版本已经支持)
目前不支持Texture Shape 为3D和2D Array的图片资源类型;
目前资源的upload by reference 模式,仅支持UGUI和NGUI,其他UI方案的贴图引用暂未测试验证过;
不支持设置为Read/write的贴图使用Texture Manager 功能。
问题一: 当一张Texture C被两个Bundle A 和 Bundle B所引用,并且Texture C并未单独打包成bundle或者也不存在与其他Bundle中,那么Texture C 就会被同时打包进Bundle A 和 Bundle B中,加载时候会导致内存中存在两份Texture C,尤其是在小游戏平台上Texture C的原始文件也会占用两份。这就导致无效的内存占用。
方案: Texture Manager 通过纹理重映射功能,会主动检测当前加载的贴图与已经存在的贴图是否相同,如果相同会将已存在于内存中的贴图关联到当前材质上,从而避免由于贴图的重复加载而导致无效的内存占用。
问题二: 小游戏一般采用ASTC格式,目前团结引擎只能支持固定的贴图格式出包。当游戏需要运行在PC上时候,采用ASTC格式需要进行Decompress 后再上传,会增加额外的内存和性能消耗。于此同时,针对同一平台的游戏,高端和低端机型性能差异较大,往往单一的ASTC格式很难适应不同机型的需求。
方案: Texture Manager的多格式支持可以解决这一问题。Texture Manager 可以支持用户设置贴图多个格式,并提供接口给用户,根据需求和机型动态的选择不同贴图格式。
问题三: 在实际游戏中,缺少良好的贴图生命周期管理,可能存在某些贴图,已经被上传到显存中,但是没有被实际使用,这些贴图会导致显存的升高问题。
方案: Texture Manager 根据场景中实际使用并引用的贴图,进行按需上传,当贴图未被使用时,会被动态卸载掉。
问题四: 当前团结引擎贴图是默认打包进入Assetbundle,在小游戏平台,当加载贴图的Assetbundle,会增加额外的Dynamic heap。
方案: Texture Manager 中贴图的文件存储是存在Js的内存中,并且会动态清理,不会增加额外的Dynamic heap。
问题四: 当前团结引擎中,加载不同的贴图,会为每个贴图单独分配一块内存用于存放贴图数据,这块数据会在目标贴图上传到GPU后释放掉;如果同时加载多张贴图,会同时分配多块内存,这就会导致内存碎片,同时也会增加Dynamic heap。
方案: Texture Manager 贴图在加载时,并不会给数据分配内存;只有当贴图实际需要上传GPU时候,才会分配一块内存,用于贴图上传到GPU。而且这块内存是复用的。基于此,可以有效的避免一次性加载贴图过多,而导致Dynamic heap变大和内存碎片。