Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Standard Shader duplicated in Asset Bundle Build

Discussion in 'Asset Bundles' started by FallenTreeGames, Dec 5, 2018.

  1. FallenTreeGames

    FallenTreeGames

    Joined:
    Jun 22, 2016
    Posts:
    25
    Hey,

    I've been investigating why our asset bundle builds use more memory than our non-bundle builds, and have narrowed it down to the shaders.

    The detailed memory view shows us that on an asset bundle build, ShaderLab takes up around 350mb, whilst on a non-asset bundle build it uses < 80mb.

    So I dumped out the list of all loaded shaders with Resources.FindObjectsOfTypeAll<Shader>() and the result is that the asset bundle build has numerous copies of some shaders, including 27 copies of the Standard shader, and 31 copies of the Standard (Specular setup) one. (The non-asset bundle build has only one copy of each).

    How do I fix this? Some of the shaders that are duplicated are custom shaders which are not being included in the correct asset bundle (so fair enough) but how do I fix this for the standard shader?
     
  2. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    200
    For built-in shaders, our current recommendation if you are using the BuildPipeline.BuildAssetBundles API is to download the built-in shaders from https://unity3d.com/get-unity/download/archive (click the drop down array next to "Downloads (Win)" or "Downloads (Mac)" to get the "Built in shaders") and copy the ones you want to de-duplicate into your project, renaming the shader internal name to something like "YourProject/Standard". From there you can then assign it to a specific bundle and it will no longer be duplicated. You will need to update all your assets to point to this shader copy instead of the original shader, this can be done with an AssetPostprocessor (https://docs.unity3d.com/ScriptReference/AssetPostprocessor.html) and reimport of your assets.

    In the Scriptable Build Pipeline, we have provided some simple code that will de-duplicate built-in shaders automatically as an example.
     
  3. FallenTreeGames

    FallenTreeGames

    Joined:
    Jun 22, 2016
    Posts:
    25
    Hey,

    Thanks for that. It was the solution I was thinking of, though I assumed it was more of a hack.

    Is the Scriptable Build Pipeline ready for production use?
     
  4. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    200
    Disclaimer: It's still in Preview, so we do not recommend it for production use.

    That being said, if you are not using Asset Bundle Variants and using full Asset Paths to load, you can try out SBP with only a single line code change and switch back if you are having issues. So far, most issues we've run into have been really simple fixes for us to track down and push out a change to fix.
     
  5. FallenTreeGames

    FallenTreeGames

    Joined:
    Jun 22, 2016
    Posts:
    25
    Okay thanks! I'll get sorting this at some point and see if I have any issues :)
     
  6. FallenTreeGames

    FallenTreeGames

    Joined:
    Jun 22, 2016
    Posts:
    25
    Hey,

    So I tried it the first way and we're still getting some duplication, think there's still some things using the default material, but it's a large project so tracking them down is hard.

    Since we're not (currently) using variants and only load scenes from the bundles, I was going to give the SBP a shot. Can you link me to the sample code that de-duplicates the shaders? @Ryanc_unity
     
    Last edited: Mar 6, 2019
  7. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    200
    Code (CSharp):
    1. public static class BuildAssetBundlesExample
    2. {
    3.    public static bool BuildAssetBundles(string outputPath, bool useChunkBasedCompression, BuildTarget buildTarget, BuildTargetGroup buildGroup)
    4.    {
    5.        var buildContent = new BundleBuildContent(ContentBuildInterface.GenerateAssetBundleBuilds());
    6.        var buildParams = new BundleBuildParameters(buildTarget, buildGroup, outputPath);
    7.  
    8.        if (useChunkBasedCompression)
    9.            buildParams.BundleCompression = BuildCompression.DefaultLZ4;
    10.  
    11.        IBundleBuildResults results;
    12.         var tasks = DefaultBuildTasks.Create(DefaultBuildTasks.Preset.AssetBundleBuiltInShaderExtraction);
    13.        ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParams, buildContent, out results, tasks);
    14.        return exitCode == ReturnCode.Success;
    15.    }
    16. }
    The key is that this uses the default task list that contains the extra tasks needed for built in shader extraction. If you look at that task source, it will give you an idea on how to make it more generic to apply to more than just built-in shaders if you want to go de-dupe crazy.
     
  8. FallenTreeGames

    FallenTreeGames

    Joined:
    Jun 22, 2016
    Posts:
    25