Search Unity

URP Default shaders and Asset Bundle

Discussion in 'Universal Render Pipeline' started by FranFndz, Jan 20, 2021.

  1. FranFndz

    FranFndz

    Joined:
    Sep 20, 2018
    Posts:
    178
    Hi there, I'm having some issues with build in URP shaders.

    I have one effect that use URP Particle Unlit. the Effect go inside an Asset Bundle..
    When I load the effect inside my APP the effects looks complete different.
    - Transparent is not working
    - Draw Order is Random
    - Emission not working

    All of those errors are from shader define/compile/feature.
    My App build in does not include all URP shaders variants (only one particles are around 3000 variants!)

    How should I solve this issue?
    Shader Graph or Shaders done by code have no problems at all.
     
  2. erikabar

    erikabar

    Unity Technologies

    Joined:
    Jan 26, 2017
    Posts:
    36
    hey @FranFndz, could you create a bug report with a small repro project? And please post your case number here so we could have a look
     
  3. FranFndz

    FranFndz

    Joined:
    Sep 20, 2018
    Posts:
    178
    ok..

    I never got any issue resolved posting to bug report, luckily where I work they pay for unity support (some times help) but forum is always better.

    Last time I sent a bug they ask me what means the number under the FPS label....I lost all hopes.

    Meanwhile.

    URP, URP Particles inside Editor
    UnityEditor.png

    Same Asset after AssetBundle and Load in Device
    Android and IOS same
    UnityDeviceAndroid.png

    As you can see the setting of the material are not being rendered (transparent, emission), so I think those variants are not inside the build.

    If I create an AssetBundle for PC/MAC and check it on Editor I got the same results as the device.
    UnityEditorAB.png


    Now, the Funny thing, if in Unity Editor i download the AssetBundle, render it (wrong), open the inspector, I click on the material to check the properties, then it render properly, some how the inspector Force the variants to compile.

    UnityEditorAB2.png
     
  4. Camarent

    Camarent

    Joined:
    Feb 19, 2014
    Posts:
    168
    It would be great if you find something that will help you to resolve this because only way I found is to use shadervariants from graphics tabs that I saved manually and added to assetbundle.
    For me it was not a problem with URP more like shaders + assetbundles.

    I can also recommend you to use scriptable build pipeline (UPM) and separate shader bundle from any other bundles so you can reference it from other bundles. It will help you with duplicated shaders.
     
  5. FranFndz

    FranFndz

    Joined:
    Sep 20, 2018
    Posts:
    178
    I do have shader variants collection for all shaders that are not build in (simple tool that collect all used shaders and create a bundle).
    So you included the build in shaders and their variants in the collection as well?
     
  6. Camarent

    Camarent

    Joined:
    Feb 19, 2014
    Posts:
    168
    Yes, I get that idea from SBP package. Not only in shader collection but in assetbundle too. They have a sample build step where they include builtin shaders in assetbundle too or they recommend to use preload shaders.
     
  7. Camarent

    Camarent

    Joined:
    Feb 19, 2014
    Posts:
    168
    For example, it is a task for creating BuiltinShader Bundle from SBP 1.8.2.

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using UnityEditor.Build.Content;
    5. using UnityEditor.Build.Pipeline.Injector;
    6. using UnityEditor.Build.Pipeline.Interfaces;
    7. using UnityEngine;
    8.  
    9. namespace UnityEditor.Build.Pipeline.Tasks
    10. {
    11.     /// <summary>
    12.     /// Optional build task that extracts Unity's built in shaders and assigns them to the specified bundle
    13.     /// </summary>
    14.     public class CreateBuiltInShadersBundle : IBuildTask
    15.     {
    16.         static readonly GUID k_BuiltInGuid = new GUID("0000000000000000f000000000000000");
    17.         /// <inheritdoc />
    18.         public int Version { get { return 1; } }
    19.  
    20. #pragma warning disable 649
    21.         [InjectContext(ContextUsage.In)]
    22.         IDependencyData m_DependencyData;
    23.  
    24.         [InjectContext(ContextUsage.InOut, true)]
    25.         IBundleExplictObjectLayout m_Layout;
    26. #pragma warning restore 649
    27.  
    28.         public string ShaderBundleName { get; set; }
    29.  
    30.         public CreateBuiltInShadersBundle(string bundleName)
    31.         {
    32.             ShaderBundleName = bundleName;
    33.         }
    34.  
    35.         /// <inheritdoc />
    36.         public ReturnCode Run()
    37.         {
    38.             HashSet<ObjectIdentifier> buildInObjects = new HashSet<ObjectIdentifier>();
    39.             foreach (AssetLoadInfo dependencyInfo in m_DependencyData.AssetInfo.Values)
    40.                 buildInObjects.UnionWith(dependencyInfo.referencedObjects.Where(x => x.guid == k_BuiltInGuid));
    41.  
    42.             foreach (SceneDependencyInfo dependencyInfo in m_DependencyData.SceneInfo.Values)
    43.                 buildInObjects.UnionWith(dependencyInfo.referencedObjects.Where(x => x.guid == k_BuiltInGuid));
    44.  
    45.             ObjectIdentifier[] usedSet = buildInObjects.ToArray();
    46.             Type[] usedTypes = ContentBuildInterface.GetTypeForObjects(usedSet);
    47.  
    48.             if (m_Layout == null)
    49.                 m_Layout = new BundleExplictObjectLayout();
    50.  
    51.             Type shader = typeof(Shader);
    52.             for (int i = 0; i < usedTypes.Length; i++)
    53.             {
    54.                 if (usedTypes[i] != shader)
    55.                     continue;
    56.  
    57.                 m_Layout.ExplicitObjectLocation.Add(usedSet[i], ShaderBundleName);
    58.             }
    59.  
    60.             if (m_Layout.ExplicitObjectLocation.Count == 0)
    61.                 m_Layout = null;
    62.  
    63.             return ReturnCode.Success;
    64.         }
    65.     }
    66. }
    67.  
     
  8. FranFndz

    FranFndz

    Joined:
    Sep 20, 2018
    Posts:
    178
    Thank, I will try to include the build in URP shaders inside the AB as well.

    Btw with my test, no issues with:
    Shader Graph (in AB)
    Shader Graph with nested SubGraph (in AB)
    Standard Build In (app build in)
    Legacy Build In (app build in)
    Shader write by code. (in AB)

    AB shaders are variantCollection and warmup.
     
  9. Camarent

    Camarent

    Joined:
    Feb 19, 2014
    Posts:
    168
    Interesting to see your results! How do you prepare your shader variant collection? Sadly I did not find any automatic way to do it.
     
  10. FranFndz

    FranFndz

    Joined:
    Sep 20, 2018
    Posts:
    178
    Well, is not that automatic, the tool base is like:
    Play the game, Debug UI have "Start Recording Shader" (what it do is clean unity variant collection and start from 0).
    Finish the stage or the scene you want the granular shader variant collection and press "Stop".
    It automatically create a variant file with all shaders and used compile/feature variants and give it the stage name (that would be inside the AB).
    This method do not include shaders variants that use shader feature that are turned ON/OFF by script (if your recorded play time didn't activate that specific feature the variant won't be inside the collection). For this issue we use Shader Compile, or have the material with the feature ON and turn it OFF on start.

    We also have a lazy tool that take all materials inside the game, look for the shaders, search the keywords and create the collection.

    But never build in shaders. lol.

    I can't put the code (work), but mostly is unity reflection
    Code (CSharp):
    1.  
    2. BindingFlags bindingFlag = BindingFlags.Static | BindingFlags.NonPublic;
    3.         MethodInfo saveCurrentSVCMethod = typeof(ShaderUtil).GetMethod("SaveCurrentShaderVariantCollection", bindingFlag, null, new System.Type[] { typeof(string) }, null);
    4.  
    5. int shaderCount = 0;
    6. MethodInfo getCurrentShaderCountMethod = typeof(ShaderUtil).GetMethod("GetCurrentShaderVariantCollectionShaderCount", bindingFlag);
    7. if (null != getCurrentShaderCountMethod)
    8. {
    9. shaderCount = (int)getCurrentShaderCountMethod.Invoke(null, null);
    10. }
    11. int variantCount = 0;
    12. MethodInfo getCurrentVariantsCountMethod = typeof(ShaderUtil).GetMethod("GetCurrentShaderVariantCollectionVariantCount", bindingFlag);
    13. if (null != getCurrentVariantsCountMethod)
    14. {
    15. variantCount = (int)getCurrentVariantsCountMethod.Invoke(null, null);
    16. }
    17.  
    18. //clear Variant
    19. BindingFlags bindingFlag = BindingFlags.Static | BindingFlags.NonPublic;
    20. MethodInfo clearCurrentVariantCollection = typeof(ShaderUtil).GetMethod("ClearCurrentShaderVariantCollection", bindingFlag);
    21.  
     
  11. Deleted User

    Deleted User

    Guest

    Facing the same issue. Our setup looks something like this:

    - Scene x is loaded from asset bundle "scene_x". Contains objects that render with URP materials.
    - URP materials and shaders are in asset bundle "assets_urp".

    Features such as alpha clipping on the Simple Lit shader do not work when loading the scene from asset bundles. Works if not using asset bundles.
     
  12. Deleted User

    Deleted User

    Guest

  13. Neto_Kokku

    Neto_Kokku

    Joined:
    Feb 15, 2018
    Posts:
    1,751
    The variant definitions exist only in materials and in variant collections. When Unity builds a bundle, only the assets assigned to that bundle are processed, all assets which belong to other bundles are ignored. So, if your material or variant collection is in bundle A, and the shader is in bundle B, when Unity builds bundle B it has no idea of which variants it actually needs to compile, and when it builds bundle A it won't compile the shader because it's supposed to be in another bundle.

    The solution, when using variant collections, is to ensure the shader is placed in the same bundle as the collection.
     
  14. FranFndz

    FranFndz

    Joined:
    Sep 20, 2018
    Posts:
    178
    Shader write by hand with variants, or shader graph with variants have no issue, all those variants are included inside the bundle. (URP Shaders I mean HLSL or Shadergraph)

    the issue is only with URP Buid-in Shaders.

    Package / Universal RP/ Shaders

    I will try this one today.

    One bundle with Build In Shaders only, or replace all build in shaders with own duplicate shaders as they mention.
    https://qiita.com/frost224/items/1860cb675ea7a581b56c

    "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."
     
    Last edited: Jan 25, 2021
  15. FranFndz

    FranFndz

    Joined:
    Sep 20, 2018
    Posts:
    178
    Ok I got one version working.

    - when creating AB build check if the shader is Build in (Package / Universal RP/ Shaders)
    - duplicate the shaders and dependencies inside your projects and rename them.
    - point to the new duplicated shaders
    - create the variants with the keys inside the shader variant collection or just add the shader with the variant (no collection)
    - it works on device
     
  16. JosephSutcliffe

    JosephSutcliffe

    Joined:
    Apr 9, 2018
    Posts:
    23
    @erikabar I'm having a similar problem where my shaders are pink.

    I have a Scene Asset Bundle that only contains a single scene, this scene has Mesh Renderers that use materials with the URP Lit shader (Screenshot 1).

    I added the shader to the Built in Shader list (From Project Settings/Graphics) and I then tried to build/compile the Scene Asset Bundle, Unity delivers variant errors (Screenshot 2) and doesn't generate the AssetBundle.

    I then created a Shader Variant Collection and added the URP Lit Shader to it, then added the Shader Variant Collection to the Preloaded Shader list (From Project Settings/Graphics) and removed the URP Lit Shader from the Built in Shader list (Screenshot 3). Then I tried to create the AssetBundle and it generates (0 errors in logs), but the materials are pink when I load the scene from the AssetBundle.

    I'm not really sure what's causing the problem.
     
  17. JosephSutcliffe

    JosephSutcliffe

    Joined:
    Apr 9, 2018
    Posts:
    23
    Here are the screenshots.
     

    Attached Files:

  18. crawfis

    crawfis

    Joined:
    Jan 30, 2014
    Posts:
    114
    Unity
    Unity
    Unity
    Unity
    ---Someone please answer this. URP with Addressables is broken (sometimes!!!!)
     
  19. KamilCSPS

    KamilCSPS

    Joined:
    May 21, 2020
    Posts:
    448
    Same issue, just can't load a scene with URP shaders at all.