Search Unity

Shader.Parse taking a long time according to Unity Profiler

Discussion in 'General Graphics' started by hedgeh0g, Sep 17, 2019.

  1. hedgeh0g

    hedgeh0g

    Joined:
    Jul 18, 2014
    Posts:
    102
    Hello folks,

    So, my scene is taking a lot time to load and, after analyzing the profiler, looks like a bottleneck is caused by this Shader.Parse. I Google'd a bit but I can't find a solution nor a reason that can explain why Shader.Parse is taking a bunch of time.

    A reasonable argument would be that I have a lot of shaders to load, but actually it isn't (unless I'm missing something, but what?).

    So, yeah. What are the common causes of Shader.Parse to take so much time? Any fixes or tests to prove that I am wrong?

    Thanks in advance.
     
  2. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Hey,

    We have been making some optimizations in this area recently because we have also noticed that it is (too) slow.
    We are currently hoping to land the improvements in Unity 2019.3.

    Are you able to share an example of a shader that was slow? Or was it one of our default shaders?
    And can you tell us the Unity version and platform you are profiling using?

    Regards,
    Richard
     
  3. hedgeh0g

    hedgeh0g

    Joined:
    Jul 18, 2014
    Posts:
    102
    Hello,

    We're currently on 2018.3.4f Win10. I can't see any specific shader being too slow, also, I can't profile the GPU because profiler says to "update my GPU drivers". Which are already up to date.

    I also tryed to preload shader like suggested here: https://forum.unity.com/threads/preloading-shaders-doesnt-help-with-performance.533838/

    If you've got any suggestion on how can I help you, please, let me know. I'll do my best.

    Cheers.
     
  4. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Thanks, it’s a CPU problem so CPU profiling is fine.

    It’s probably not going to be the fault of any particular shader, but I was curious in case you knew of any specific ones that were problematic. We have seen it on many of our default shaders though.

    I’m not sure we are going to be able to land any improvements to this area in Unity 2018.4 now as it’s not a serious bug, just an inefficiency. But if your project will be running for long enough that Unity 2019.3 might be a viable option, it may help you as we are seeing a 35% speedup in this area in our local testing, and hope to land the optimisation in a public build in the coming weeks. But I’m always wary of advising upgrades because it comes with a lot of risk to you.
     
  5. TokyoWarfareProject

    TokyoWarfareProject

    Joined:
    Jun 20, 2018
    Posts:
    814
    Hi,
    on loading map, for Xbox, I've a gigangic spike due to Shader.Parse too. On PC is not that much of a deal but its because I've a powerfull one.
    I use standard shader like for 99,9% of the stuff in scene.
    That GPU drivers message, try dissabling graphics jobs may be I think I did get that message in the past.
    Last time on certification they called my attention on this issue because it kinda freezes right before launching the match... 2018.4.9f1
     
  6. TokyoWarfareProject

    TokyoWarfareProject

    Joined:
    Jun 20, 2018
    Posts:
    814
    profiling xbox build
    upload_2019-11-24_21-32-14.png
     
  7. austinborden

    austinborden

    Joined:
    Aug 5, 2016
    Posts:
    24
    @richardkettlewell Is this issue tracked anywhere? I'd like to see if the improvements have been added to any Unity 2019 version.
     
  8. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    I don’t know if it’s on the issue tracker anywhere but we landed most of our improvements to 2019.3, and some more only made it into 2020.1 (unfortunately)
     
  9. adamgryu

    adamgryu

    Joined:
    Mar 1, 2014
    Posts:
    188
    I recently noticed after upgrading from 2018.4.2 to 2018.4.23 that I'm getting large Shader.Parse spikes where I didn't before (while async loading a scene). Is there any way to get around this? Prewarming the shaders seems to make no difference now.
     
  10. adamgryu

    adamgryu

    Joined:
    Mar 1, 2014
    Posts:
    188
    I ended up updating all the way to 2019.3, which removed the stutter introduced in 2018.4.23. Now I just have to QA my entire game again :p
     
  11. RubberBandGames

    RubberBandGames

    Joined:
    Jul 20, 2020
    Posts:
    170
    We're on 2020.1.0f1 and having this exact issue on Xbox. Any updates?
     
  12. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Hey, no updates that are useful to you right now, but a colleague is investigating whether we can distribute this work across multiple threads.
     
  13. Neto_Kokku

    Neto_Kokku

    Joined:
    Feb 15, 2018
    Posts:
    1,751
    If you are using asset bundles built with the legacy build pipeline (like Asset Graph) it simply does not support assigning built-in Unity assets to bundles (including built-in shaders and built-in meshes like Plane and Cube). The legacy pipeline can only assign asset bundles based on asset paths and the built-in assets don't have a valid one (also, AssetDatabase.GetDependencies() does not detect built-in assets either).

    What happens when building the bundles is that the built-in assets referenced by the assets in your bundles get the same treatment as any other dependency that doesn't have a bundle assigned to it: it gets copied into each asset bundle that depends on it.

    This is why using ShaderVariantCollections to warm up built-in shaders fail: each bundle will load a fresh copy of the shader, that needs to be Shader.Parse'd into the GPU again for each newly loaded bundle.

    The ContentPipeline API behind the Scriptable Build Pipeline is capable of assigning bundles to built-in assets, since it assigns bundles by asset reference, not paths. It also has dependency collection functions that, unlike AssetDatabase, can detect built-in assets correctly (it even correctly reports built-in shaders set as custom shader fallbacks as dependencies).

    However, depending on how far along your project and how it's set up, switching from legacy to scriptable build pipeline is not feasible (there's also the question of the SBP being newer, not as battle-tested as legacy, and largely undocumented beyond very basic use cases).

    The "solution" then is to download the built-in shaders for your Unity version, move them all into your project, then replace all references to the built-in shaders by the imported ones. This way you can assign them to a bundle that will be correctly registered as a dependency of any other bundles that reference them, and you can put them into a ShaderVariantCollection (loaded from a bundle) and warm up them correctly.