当前位置: 首页 > news >正文

Unity5.x shader打包AssetBundle总结

Unity5.x shader打包AssetBundle总结

https://gameinstitute.qq.com/community/detail/120395

大家的项目中如果用的是unity5.x,可能在面对这个新的包机制可能不知道怎么使用,为了帮助大家,下面就将在打包shader的时候会遇到的一些问题分享给大家。

 

在上一个项目中,我们使用unity4.7,对于shader并没有进行依赖打包,而是由unity打包到了每个用到的AssetBundle中去,其实这样是“很不科学的”。这样不仅增加了ab的总体积,而且还会在运行时产生很多的shader实例,增加很多的显存占用。所以我们决定把自定义的shader打包成一个AssetBundle。

 

用到的工具:

1、UnityStudio:https://github.com/Perfare/UnityStudio/releases

这是一个解包AssetBundle的工具,可以查看和导出ab中的资源。

2、Unity自带的profiler

 

下面是一些尝试和结果分析:

一、不进行依赖打包(不需要设置GraphicsSetting,不给自定义shader设置AssetBundle Name)

这种情况unity5.x还是与unity4.x一样,把shader打包到每一个使用它的AssetBundle 中去,这样就会同时存在多个一样的shader,并在运行时产生多个shader实例。

如下图:

这个Character是我们自定义的一个shader,在运行时产生了多个实例:

 

使用UnityStudio解包一个ab可以看到,我们自定义的shader ParticlesAlphaTintColor被打包到ab中:

 

打包后的运行测试结果如下:

1、编辑器是pc平台的时候,打出来的包在编辑器里运行是正常的。

2、编辑器是安卓时,打出来的包在编辑器里运行显示粉红(查看材质可以发现并不是丢失材质和shader),但在手机正常。

这是为什么呢?这是因为以安卓为平台打包的时候被打包的shader被编译成安卓平台的版本,在unity编辑器中运行会发生异常。这是从4.x到5.x一直有的问题。

解包后我们可以看到不同平台编译出来的shader subProgram不同。

Pc:

 

 

安卓:

 

 

二、依赖打包(将shader设置AssetBundle Name打包)

使用这种方式,需要将shader添加到GraphicsSetting-> always included shader设置中,否则shader也会显示粉红。注意要在设置Graphics之后把shader重新打包,在能生效。

文档中也有说到:https://docs.unity3d.com/Manual/class-GraphicsSettings.html

 

 

测试结果如下:

1、编辑器是pc平台的时候,打出来的包在编辑器里运行是正常的。

2、编辑器是安卓时,打出来的包在编辑器里运行显示粉红(查看材质可以发现并不是丢失材质和shader),但在手机正常,原因同上。

 来自:http://blog.csdn.net/zhaoguanghui2012/article/details/53930972

再使用profiler查看,可以发现shader可以被物体共用了,随着物体数量的增加也不会产生多个shader实例。(下图有两个Character是因为编辑器中ShaderVariantCollection跟踪到了这个shader,也算一个引用)

 

这时解包模型的ab,也不会看到shader被打进ab中了,它们只存在与自己的ab包中。

 

三、注意事项

1、细心的朋友会发现,一中我们profiler中看到的Character是45.7k,而二中是334k,这是因为Character是一个多变体的shader,而加入了GraphicsSetting-> always included shader后,会将它所有的变体打包到游戏中。

 

2、在测试打包的过程中我发现一个有趣的现象--- unity5.4和4.x打包后的shader解包(非依赖打包)出来看起来不一样:

 

5.4没有看到代码,而是看到GPUProgramID

 

而4.7是直接看到代码

 

结合最新更新的unity5.5的更新日志,似乎可以看出点端倪:https://Unity3D.com/cn/unity/whats-new/unity-5.5.0

---Shaders: Shaders are now exported to the Unity player completely in binary. There is no Shader text string and parsing in run time.

 

3、关于untiy内置shader

如果没有设置到GraphicsSetting-> always included shader中,那么会打包到依赖它的ab中,如果设置了就不会打包进去。而是再构建的时候,就导入到你的游戏。

 

4、手动设置shader 加入GraphicsSetting-> always included shader很麻烦,怎么办?

其实是可以使用代码设置的:

[MenuItem("Test/测试设置included shader", false, 11)]  
 public static void TestIncludedShader()  
 {  
     string[] myShaders = new string[1]{  
         "Legacy Shaders/Diffuse"  
     };  
     SerializedObject graphicsSettings = new SerializedObject (AssetDatabase.LoadAllAssetsAtPath ("ProjectSettings/GraphicsSettings.asset") [0]);  
     SerializedProperty it = graphicsSettings.GetIterator ();  
     SerializedProperty dataPoint;  
     while (it.NextVisible(true)) {  
         if (it.name == "m_AlwaysIncludedShaders") {  
             it.ClearArray();  
             for (int i = 0; i < myShaders.Length; i++) {   
                 it.InsertArrayElementAtIndex(i);  
                 dataPoint = it.GetArrayElementAtIndex (i);  
                 dataPoint.objectReferenceValue = Shader.Find(myShaders[i]);  
             }  
             graphicsSettings.ApplyModifiedProperties ();  
         }  
     }  
 }  

 

 

5、加入AlwaysIncludedShaders的shader是开始游戏的时候就全部编译了吗?

答案是不会,加到always include 的shader,会将shader的所有变体打包到游戏,用到的时候才会加载用到的变体到内存!需要预加载变体可以使用:ShaderVariantCollection

相关文档:https://docs.unity3d.com/Manual/OptimizingShaderLoadTime.html

 

 

值得注意的是unity5.x内置的  Standard shader是一个有成千上万变体的shader,要谨慎的把它加入到GraphicsSetting-> always included shader,因为1中的原因,会使得你的包体非常大,打包也非常耗时。至少在我测试下是一直卡在这个界面到下班都没有响应。。

文档里面也有提到:

 

原文链接

 

 

 

 

相关文章:

  • Unity 加载AssetBundle
  • Unity开发(三) AssetBundle同步异步引用计数资源加载管理器
  • Unity脚本运行时更新带来了什么?
  • UE4 补丁更新(基于Http)
  • UE4 Pak加载
  • Unity3D Shader加载时机和预编译
  • ShaderVariantCollection解决shader_feature丢失
  • 一次UNITY闪退问题的定位心得
  • Unity AssetBundle打包 , BuildAssetBundleOptions
  • protobuf-net 的应用
  • Using Unity’s ShaderVariantCollection
  • Unity技术分享连载(64)|Shader Variant Collection|Material.SetPassFast
  • 最新的asmdef定义的模块中,VisualStudio中无法引用UnityEngine.iOS.XCode命名空间
  • UNIYT关于V S2017,VS2019断点调试卡住的问题
  • Mac上用VS Code调试 Unity程序
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 10个确保微服务与容器安全的最佳实践
  • android 一些 utils
  • Angularjs之国际化
  • javascript数组去重/查找/插入/删除
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • NSTimer学习笔记
  • overflow: hidden IE7无效
  • yii2权限控制rbac之rule详细讲解
  • 闭包--闭包作用之保存(一)
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 简单基于spring的redis配置(单机和集群模式)
  • 理清楚Vue的结构
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 模型微调
  • 前端自动化解决方案
  • 删除表内多余的重复数据
  • 双管齐下,VMware的容器新战略
  • 新手搭建网站的主要流程
  • 最简单的无缝轮播
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • (14)Hive调优——合并小文件
  • (转)一些感悟
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .net core 客户端缓存、服务器端响应缓存、服务器内存缓存
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .NET Micro Framework初体验
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .NET 中 GetProcess 相关方法的性能
  • .NET/C# 的字符串暂存池
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表