Search Unity

ShaderVariantCollection - how does it work?

Discussion in 'Shaders' started by sirrus, Jun 29, 2015.

  1. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Can someone please explain to me how ShaderVariantCollections are supposed to work?

    Here's the issue we are experiencing:

    We create numerous assets using different configurations of the Standard Shader (different render modes, normal maps, etc). These different configurations are saved in a ShaderVariantCollection asset via the Project Graphics Settings in the Editor and the collection is included in the preloaded shader section. My understanding is that when these assets are then downloaded via assetbundle in a build, the ShaderVariantCollection should recognize the different configurations and render the assets appropriately. This isn't happening as the build (in this case a webplayer project) always displays them using the default Standard shader properties.

    The only way we can seem to register the proper shader configurations is to include a material in the project that has the settings we want and then force them via script. (See the final post in this thread of others using the same method):

    http://forum.unity3d.com/threads/access-rendering-mode-var-on-standard-shader-via-scripting.287002/

    The Standard Shader is included in the Always Included Shader section as well (is this necessary?)

    Thanks for any help,

    sirrus
     
  2. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Sorry to bump but I never received any answer on this and am still having problems with this system. Even when certain shader variants are detected by Unity and placed in the collection, they still do not seem to work at runtime (in editor).

    Any thoughts?
     
  3. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    There are variants that are always available (multi_compile) and variants that are not always available (shader_feature). Differences in light sources, forward and deferred and fog are done using multi_compile. Differences in having a normal map or not are done using shader_feature.

    The ShaderVariantCollection object is from before the shader_feature function, so I don't think this will help with this issue.

    One way is to indeed just use all combinations you need on actual materials in the scene. The assigned maps can be dummies sized 1x1, but that will include the optional shader variant in the project.

    Another way would be to make a copy of the standard shader and change shader_feature to multi_compile where you need the different shader variants to be available. Then use this shader instead. Note that shader_feature is there for a reason, the number of variants can quickly increase. If you just need to be able to switch a few options though, it should be fairly harmless. You could even get some breathing room by disabling fixed features if you don't use them.

    Here's the original from the standard shader in the deferred pass:
    Code (csharp):
    1.  
    2. #pragma shader_feature _NORMALMAP
    3. #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    4. #pragma shader_feature _EMISSION
    5. #pragma shader_feature _METALLICGLOSSMAP
    6. #pragma shader_feature ___ _DETAIL_MULX2
    7. #pragma shader_feature _PARALLAXMAP
    8.  
    9. #pragma multi_compile ___ UNITY_HDR_ON
    10. #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
    11. #pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    12. #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
    13.  
    Lets say you want to have the options to have blending and a normal map, but you're not using directional lightmaps or hdr. You can change it to:
    Code (csharp):
    1.  
    2. #pragma multi_compile _NORMALMAP
    3. #pragma multi_compile _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
    4. #pragma shader_feature _EMISSION
    5. #pragma shader_feature _METALLICGLOSSMAP
    6. #pragma shader_feature ___ _DETAIL_MULX2
    7. #pragma shader_feature _PARALLAXMAP
    8.  
    9. //#pragma multi_compile ___ UNITY_HDR_ON
    10. #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
    11. //#pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED DIRLIGHTMAP_SEPARATE
    12. #pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
    13.  
     
    sirrus likes this.
  4. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    @jvo3dc, thanks for the response. We have included materials in the scene as a test case and it didnt seem to work in the editor. Im beginning to wonder if it is an editor bug. We are testing actual builds now to see if that's the case.

    Though we have copied/modified the standard shader, I will look into the multi_compile flag to see if that will help in this case as well.
     
  5. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    Are you switching material properties in realtime? Or loading parts? (And the latter case, from Resources, WWW or through LoadLevel?)
     
  6. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    In these test cases we are not changing material properties or components. It's basically a prefab downloaded via assetbundle. We previously had to make material modifications via script at runtime to register the proper render mode (see link in original post). We are no longer doing that in our tests and it appears that the properties render correctly in a BUILD, just not the EDITOR.
     
  7. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    I have similar experiences when downloading through www. There seems to be a difference between the editor and builds.

    The intention seems that you can overwrite shaders in an assetbundle with shaders in the scene, but I see nothing about that in the documentation. That would allow you to change a shader without updating all your assetbundles, which makes sense. Scripts in an assetbundle can be overwritten in a similar way.
     
  8. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    The capability of overwriting shaders is fine, but if assets render completely improperly (by default) in the editor when downloaded via assetbundle, that seems like a pretty significant bug to me.
     
  9. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    Yes, it seems a bug related to the combination of shader features with the overwriting ability when downloading assetbundles.
     
  10. zzd

    zzd

    Joined:
    Jul 6, 2012
    Posts:
    3
    Hi,sirrus,is this question ok now?how to do,and now I use 2017 version,still have this question
     
  11. sirrus

    sirrus

    Joined:
    Jun 10, 2012
    Posts:
    250
    Part of the issue was that assetbundles dont usually load properly in the editor. This is because they may be built for a different target than the current running platform (i.e, built for WebGL, running in Windows Editor). This will prevent shader variants from registering properly thus making the variant collection not work (in this case).
     
    glenneroo likes this.