Search Unity

  1. Check out the Unite LA keynote for updates on the Visual Effect Editor, the FPS Sample, ECS, Unity for Film and more! Watch it now!
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Shader.Find returns null for asset bundles (Repro included)

Discussion in 'Asset Bundles' started by BinarySpark, Oct 25, 2018.

  1. BinarySpark

    BinarySpark

    Joined:
    Sep 18, 2018
    Posts:
    3
    Hi,

    We're having a problem where shaders that are loaded from AssetBundles cannot be found by the game.

    In the Postprocessing Stack v2, shaders are used in one of two ways: either through Shader.Find, or through a direct reference in PostProcessResources.asset. When the shaders are loaded from an AssetBundle, neither method works. Shader.Find just returns null.

    The attached project demonstrates this. The Loader scene loads the shared asset bundle (which contains the postprocessing resources in this project), then loads the scene bundle, then switches to that scene.

    TL;DR: So we're at a loss here. The postprocessing stack doesn't work because the required shaders cannot be found.

    We are using Unity 2017.4.10, and we cannot (easily) upgrade Unity versions because we're doing console development. We've already been redirected from the console-specific forum to this general Unity forum, so I hope we can get some help here. :)

    Expected output:
    a001-expected.jpg

    Observed output:
    a002-observed.jpg

    Repro steps: (produces 'observed output')
    1. Open the attached project, for target platform Standalone Windows 64.
    2. Make a development build by clicking Tools > Build Debug for Active Target. (This will build asset bundles too.)
    3. When finished, find the executable file at 'Build/StandaloneWindows64/ShaderFindBug.exe'.
    4. Launch the player.
    5. Observe that in the main scene with the cubes, there is no postprocessing (bloom and vignette).

    Alternate repro steps (without asset bundles, produces 'expected output'):
    1. Delete the Assets/StreamingAssets/AssetBundles folder, if present.
    2. In File > Build Settings, disable the Loader scene, and enable the ExampleScene scene.
    3. Make a build, and launch the player.
    4. Observe that in the main scene with the cubes, bloom and vignetting works as expected.

    Other things we've already tried:
    • Verifying that the shaders are actually in the bundle, by calling AssetBundle.GetAllAssetPaths() and checking the output.
    • Calling Shader.WarmupAllShaders() after loading the asset bundles.
    • Forcefully calling assetBundle.LoadAllAssets<Shader>() to ensure they are loaded in memory.
    • Putting the shaders in a Resources folder.
    • Adding the shaders to GraphicsSettings' Always Included Shaders. This works mostly, however some references still break - a few shaders still can't be found, and references to some lookup textures break.

    This is looking to us like some oddity, or perhaps a bug, in Unity itself. If anyone has any ideas as to what's going on and how we could fix this, or if we've maybe missed something, we'd really appreciate it.
     

    Attached Files:

  2. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    146
    Are you using Shader.Find in runtime code? or is the PostProcessing stack doing that?
    Edit: looking at the repro project...one min
     
  3. BinarySpark

    BinarySpark

    Joined:
    Sep 18, 2018
    Posts:
    3
    Hi Ryanc,

    The Shader.Find calls are made in Postprocessing Stack v2 code, not ours.

    I still suspect that this is an oddity or bug in Unity's internals, however currently we've worked around it. For any future readers with the same problem: what worked for us is replacing the Shader.Find calls (specifically those in the copy and copyStd material getters) with direct references pulled from the PostProcessResources ScriptableObject. Any custom shaders and effects can be added to that group as well, so the shaders can be pulled from there.

    e.g.
    context.resources.shaders.copyStd
    or
    context.resources.shaders.myAwesomeShader
     
  4. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    146
    Talked with the Post Processing team, and they have a fix they are pushing out for this in the next release (2.0.18).
    For Reference: Shader.Find API does not work with shaders loaded from AssetBundles.
     
    Peter77 likes this.
  5. BinarySpark

    BinarySpark

    Joined:
    Sep 18, 2018
    Posts:
    3
    Awesome, thank you for the help! :D