Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question ShaderVariantCollection to use with assetbundles

Discussion in 'Shaders' started by Deliriom, Nov 23, 2023.

  1. Deliriom

    Deliriom

    Joined:
    Mar 20, 2018
    Posts:
    6
    Hello

    Our software is a sort of a 3d viewer which works with an external assetbundle database. Each item that can be viewed comes as an assetbundle, downloaded at runtime.

    The assetbundles are created by our graphics team, and they all use Unity’s standard shaders, but not with all the features.

    I am having trouble determining the shader variants we need in the viewer build. Here are the features we use:

    - no lighting in the viewer, just baked lighting data coming from a skybox
    - lighting in the assets is baked into the textures in Substance, using the same skybox
    - the camera can switch between forward and deferred rendering (optional post processing )
    - all blend modes are used (opaque, cutout, transparent and fade)
    - albedo, normal maps, smoothness/metallic maps, occlusion maps and emission maps can be encountered on the assets (any combination of them, or none)
    - no height maps or detail maps
    - when emissive is active, the global illumination setting is sometimes none, sometimes realtime, I thought it did not matter since we don't have one...
    - specular highlights and reflections are sometimes checked, sometimes not, I also thought it did not matter.

    Based on this I thought that we can keep only variants with ForwardBase and Deferred tags, and then exclude any that contain Parallax, Detail, Directional, Point…

    But we have many missing shaders in that case. I activated strict variant matching to check which ones. The problem is that the log about the missing variants does not have the same format as the variants in the shader collection, so I don’t know what we need to add.

    So here are my questions:
    - what does this log mean for instance?
    Shader Standard (Specular setup), subshader 1, pass 0, stage pixel: variant LIGHTPROBE_SH _ALPHABLEND_ON _EMISSION _NORMALMAP _SPECGLOSSMAP not found.

    I have included this exact combination of keywords for passType 0, 4 and 10. I don't know what 0 stands for, I guess "normal" (or "always"??), and I saw that 4 is for ForwardBase and 10 for Deferred. How do I know which passtype is missing? Or maybe some keyword is missing?

    - is it worth bothering with stripping variants or is it simpler to include the whole shader in our case? Also, if I place the standard shader in the Always included shaders, will it stay on build or will the unused variants still get stripped?

    - is it enough to place the shader variants collection in a Resources folder or do we have to add it to the preloaded shaders section in Graphics settings?

    - in our case, what does the graphics settings « export asset » do? Does it include recently encountered variants in play mode? Or only ones from assets in our project? If I run a script in editor runtime, generating all sorts of materials, will it include their variants?

    - is there a more efficient way to do all this?

    Thank you for reading through, I know it was long, I hope it was clear enough..
     
  2. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    2,956
    Hi!
    The numbers here mean the subshader index and the pass index in the shader.
    It's definitely worth it to strip variants. There are too many if you don't.
    Shaders placed in the Always included shaders list include all their variants without stripping.
    These are variants that the Editor encountered, yes.
    Yes, if the Editor will need to render them.
    Unfortunately, not.
     
  3. Deliriom

    Deliriom

    Joined:
    Mar 20, 2018
    Posts:
    6
    Hi, thank you very much for your answer.
    I did a ~quick~ test this morning:
    - on scene load I generate 1024 cubes with different materials. At this stage I can see that the tracked shaders and variants in graphics settings increase a lot, which is cool
    - then I turned off the AO, switching the camera to forward rendering, and the tracked variants increased again, still cool.
    - I saved the shadervariantcollection asset in my Resources folder and built.

    When I launch the build:
    - I can see all my cubes in Deferred (although there are many logs about variants not found, subshader 0, pass 2 which is deferred)
    - all 1024 cubes are magenta in Forward (and of course, more logs, about subshader 0, pass 0, which is forward base)

    When I search for the missing variants from the logs in the shader collection, I can't find them, indeed, there is always an additional keyword - either LIGHTPROBE_SH or DIRECTIONAL

    Here is an example:
    Shader Standard, subshader 0, pass 0, stage pixel: variant LIGHTPROBE_SH _ALPHATEST_ON _METALLICGLOSSMAP not found.

    And in the collection I have an exact match for deferred, and an additional keyword for forward:
    Code (CSharp):
    1.       - keywords: DIRECTIONAL LIGHTPROBE_SH _ALPHATEST_ON _METALLICGLOSSMAP
    2.         passType: 4
    3.    
    4.       - keywords: LIGHTPROBE_SH _ALPHATEST_ON _METALLICGLOSSMAP
    5.         passType: 10
    How should I handle that? Thanks!
     
  4. Deliriom

    Deliriom

    Joined:
    Mar 20, 2018
    Posts:
    6
    I did another test:
    While generating the cubes, I placed all variants manually into a collection, which does look exactly like expected, but I still get missing shaders logs (and pink cubes in forward), even though now I can see the exact set of keywords from the logs in the shader variants collection.

    And if I put the collection in the preloaded shaders, on preload I get 272 messages for missing variants per shader (out of the 512 expected variants). I'm guessing I may have created invalid variants, although I'm not sure what's invalid about them
    Example
     Shader Standard, subshader 0, pass 0, stage vertex: variant _NORMALMAP not found. 
     
  5. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    2,956
    I think what happens is that Standard shader cannot have only
    _NORMALMAP
    enabled. Most likely there are directives that do not allow for "no keyword enabled".
     
  6. Deliriom

    Deliriom

    Joined:
    Mar 20, 2018
    Posts:
    6
    Hi! Thank you again for your replies, much appreciated, and sorry for the long absence (Covid hit me..)

    I tried manually creating a material using Standard shader and just a normal map.
    When displaying it on an object in the scene, two new variants are detected by the Graphics Manager


    Code (CSharp):
    1.       - keywords: DIRECTIONAL LIGHTPROBE_SH _NORMALMAP
    2.         passType: 4
    3.       - keywords: LIGHTPROBE_SH _NORMALMAP
    4.         passType: 10
    So, as I said above, the `DIRECTIONAL` and `LIGHTPROBE_SH` keywords appear from somewhere.

    However, when debugging the material I get this:
    - `material.enabledKeywords` returns just `_NORMALMAP`
    - `material.IsKeywordEnabled("DIRECTIONAL")` returns false
    - `material.shader.keywordSpace.keywords` returns all possible keywords there are
    - `Shader.enabledGlobalKeywords` returns UNITY_HDR_ON

    My question is where do these keywords come from? I was thinking that instead of generating objects, then displaying them in the scene, then using the GraphicsManager to export the collection, I could just create the collection programatically. But indeed, that would not be possible if unknown keywords need to be added.

    Can I just assume that I need to add `LIGHTPROBE_SH` to all the variants in the collection, and `DIRECTIONAL` to all that have pass type `PassType.ForwardBase` ?

    I am sorry if my understanding of the whole thing is insufficient, thank you for bearing with me!
     
    Last edited: Dec 4, 2023
  7. Deliriom

    Deliriom

    Joined:
    Mar 20, 2018
    Posts:
    6
    Actually, I am wondering if I should pursue this at all.

    I did a test in a new empty project:
    - Just one scene, no light, and a capsule with a Standard material on it
    - If I check the "strict matching" in the player settings, I cannot get the capsule to display correctly. I tried all of these:
    * Just build (the variant should be included, since the capsule is in my scene)
    * Put the material in a Resources folder
    * Include the entire Standard shader in the Always included shaders
    * Create a shader variant collection from graphics settings and put it in the resources folder
    * Put the collection in the preloaded shaders in graphics settings

    The result is always a pink capsule.

    I was assuming that checking the "strict matching" box would help me make sure I've included everything I need. Previously these checks were performed by simply testing the build and crossing our fingers, I'm guessing it could still be the best way.

    Would you happen to know what's going on? Thank you!

    **EDIT** I'm working with version 2022.3.14f1
     
    Last edited: Dec 4, 2023