zoukankan      html  css  js  c++  java
  • Unity5.x shader打包AssetBundle总结

    最近比较忙,好久没有更新博客了,新项目切换到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),但在手机正常,原因同上。

    再使用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很麻烦,怎么办?

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

    来自:http://www.hiwrz.com/2016/04/18/unity/175/

    [csharp] view plain copy
     
    1. [MenuItem("Test/测试设置included shader", false, 11)]  
    2.  public static void TestIncludedShader()  
    3.  {  
    4.      string[] myShaders = new string[1]{  
    5.          "Legacy Shaders/Diffuse"  
    6.      };  
    7.    
    8.      SerializedObject graphicsSettings = new SerializedObject (AssetDatabase.LoadAllAssetsAtPath ("ProjectSettings/GraphicsSettings.asset") [0]);  
    9.      SerializedProperty it = graphicsSettings.GetIterator ();  
    10.      SerializedProperty dataPoint;  
    11.      while (it.NextVisible(true)) {  
    12.          if (it.name == "m_AlwaysIncludedShaders") {  
    13.              it.ClearArray();  
    14.    
    15.              for (int i = 0; i < myShaders.Length; i++) {   
    16.                  it.InsertArrayElementAtIndex(i);  
    17.                  dataPoint = it.GetArrayElementAtIndex (i);  
    18.                  dataPoint.objectReferenceValue = Shader.Find(myShaders[i]);  
    19.              }  
    20.    
    21.              graphicsSettings.ApplyModifiedProperties ();  
    22.          }  
    23.      }  
    24.  }  



    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中的原因,会使得你的包体非常大,打包也非常耗时。至少在我测试下是一直卡在这个界面到下班都没有响应。。

    文档里面也有提到:

     

    6、关于shader加载和预热的一些资料:

    Unity - Manual: Optimizing Shader Load Time

    https://docs.unity3d.com/ScriptReference/ShaderVariantCollection.html

    http://www.seven-fire.cn/archives/174

    https://www.zhihu.com/question/30087487

    https://zhuanlan.zhihu.com/p/21949663

  • 相关阅读:
    今天的学习
    sql&nbsp;修改字段
    原来这个分类是powerdesigner
    sql&nbsp;sum&nbsp;&nbsp;&nbsp;&nbsp;空或0
    mac 配置maven报zsh: command not found各种坑点走位
    java-Map集合中存入的数组值转存到ArryList集合中的实现
    Java-集合总结之Collection和Map--Map(3)
    Java-集合总结之Collection和Map--Set(2)
    Java-集合总结之Collection和Map--List(1)
    测试-bug跟踪过程中的相关状态英文释义
  • 原文地址:https://www.cnblogs.com/lancidie/p/8471771.html
Copyright © 2011-2022 走看看