Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    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:
    332
    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:
    332
    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
     
  6. qixaxe

    qixaxe

    Joined:
    Sep 4, 2015
    Posts:
    1
    Hi, we seem to be having a similar problem. Ryanc mentioned that a fix was pushed in 2.0.18, but I don't know how to map that to a Unity version (we're using 2018.4.10f)
     
  7. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    332
  8. MarkSutton

    MarkSutton

    Joined:
    Sep 25, 2017
    Posts:
    2
    Update from 2022.3.3 - I think this problem still exists. Shader.Find is returning null for me when shaders are loaded as part of an asset bundle (our asset bundles are streamed scene asset bundles). Have thrown a fair bit of time at this and ruled out everything else I can think of, so am fairly sure it's the same issue, not yet fixed.

    For those who are struggling with this, I've used a similar workaround to BinarySpark above - rather than use Shader.Find, I've recoded to use references to shaders from materials within the scene, which does the job.