Search Unity

2 minute load time between splash image and first scene on Xbox One

Discussion in 'Windows' started by Ayrik, Feb 5, 2019.

  1. Ayrik

    Ayrik

    Joined:
    Aug 31, 2008
    Posts:
    430
    During this 2 minute load time where it's compiling shaders, the screen is just black. I've tried having a simple scene up front to let it just load something, but no, it compiles all the shaders first.

    Meanwhile, during this load time my customers think the game is broken and it's just a bad experience overall.

    So, I've tried to learn about this C++ XAML nonsense but I can't wrap my head around how to open a loading window overtop of the Direct3D canvas but I just can't seem to get a grip on it.

    Any help would be greatly appreciated.
     
  2. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    Hey,

    that's weird you're seeing this behaviour. Let's first see if we can figure out what's causing this loading delay. How do you know that's it's shaders compiling? How did you profile it?

    As for the loading screen: there are several options. Which Unity version are you on? Do any of your scripts (Start(), Awake()) get called before the long delay starts, or do they only get called after the delay?
     
  3. Ayrik

    Ayrik

    Joined:
    Aug 31, 2008
    Posts:
    430
    @Tautvydas-Zilys thanks for responding. The shader precompilation spams the Visual Studio output when the debugger is attached.

    As far as scripts go, my first scene simply waits for the personal edition splash screen to complete and then load the next scene.

    Oh, and also, the first scene also has UI displaying a loading spiral and background, which does not show up ever. This is the correct behavior based on the code below, but not ideal since it's just black for 2 minutes before the Unity splash shows.

    Another thing. When removing the first scene that waits for splash to finish, the same issue occurs.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Rendering;
    5. using UnityEngine.SceneManagement;
    6.  
    7. public class Init : MonoBehaviour
    8. {
    9.     public string mainMenuScene;
    10.  
    11.     private IEnumerator Start()
    12.     {
    13.         while(!SplashScreen.isFinished)
    14.             yield return null;
    15.  
    16.         Debug.Log($"Init.Start '{mainMenuScene}'");
    17.         SceneManager.LoadScene(mainMenuScene);
    18.     }
    19. }
    20.  
    Thanks again!
     

    Attached Files:

    Last edited: Feb 6, 2019
  4. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    Are you running a debug build? Did you try running in Release to see if that improves the loading time?

    Secondly, is your game configured as 'Game' on Xbox instead as 'App'? That can severely impact performance: https://docs.microsoft.com/en-us/windows/uwp/xbox-apps/system-resource-allocation. You can configure it after deploying the game and going into its properties on the Xbox.

    Thirdly, in the editor there's a setting called "Always included shaders": https://docs.unity3d.com/Manual/class-GraphicsSettings.html#Always. That can significantly increase shader loading times at startup. Is there any chance you added anything to it?

    Lastly, after reading your post I'm still not sure whether any of your scripts get to execute while the screen is black. Could you clarify on that?
     
  5. Ayrik

    Ayrik

    Joined:
    Aug 31, 2008
    Posts:
    430
    This is with Master. And this game is already in the store this way. MasterWithLTCG also did not improve it.

    It is marked as Game and this is happening on retail devices.

    There is nothing in the Always included shaders.

    And no, there is no script running at this time. The only one is the script mentioned above and it does not start running until the Unity splash screen starts. In fact, the wait for debugger popup isn't even opened until after this time as well. You can see from the log output that it's compiling HUNDREDS of shaders and it even states how much time it takes. In this case it is 52 seconds, but I have customers saying that it can be much longer, like after a hard boot when there's no cache warmed up.
     
  6. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    Ouch, that sounds brutal. Do you know how long it takes on PC?

    One option would be to switch to XAML build type. With it, there's an element called "ExtendedSplashScreen". You can set it to any image - by default it is set to your normal splashscreen. However, I'm not sure whether that will have any impact on performance or input (it might).

    Another option would be to draw an loading screen image from generated VS project BEFORE initializing Unity, presenting it to the screen, tearing down D3D and then calling into Unity. That thing would remain on the screen until Unity draws its first frame - the splashscreen. However, that would require a little bit of coding. Let me look into whether there are any other solutions before going this route.
     
  7. Charles_Sanglimsuwan

    Charles_Sanglimsuwan

    Unity Technologies

    Joined:
    Feb 10, 2017
    Posts:
    69
    This may be due to having a lot of shader variants in your project. When shaders compile at runtime, they can expand into many variants due to #pragma multi_compile or shader_features.

    Are you using any visual shader editors, such as Amplify or Shader Forge? Those editors tend to create a lot of variants, and in some cases, causing titles to see longer loading times due to shader compilation.

    What I would suggest is to audit all of your shaders, finding only the discrete set of shader variants that you actually need. Then use ShaderVariantCollection to load them as they are required.
     
  8. Ayrik

    Ayrik

    Joined:
    Aug 31, 2008
    Posts:
    430
    No I don't use any of those. Just your PostProcessing stack and TextMeshPro which I'm told generates a lot of shader variants. But, this is a very old project, with hundreds of assets all using legacy shaders mixed the standard shaders, and so there are probably a lot of shaders to compile.

    Either way, I feel like it's a bug that I'm not able to put something up during this, or that Unity isn't displaying my splash screen by default.

    Also, @Tautvydas-Zilys it is virtually instant on PC. I didn't know about the XAML method so I'm going to test performance on that right now, but I am certainly not hopeful. And also, that second option is the one I mentioned in my first post that I tried and failed because I can't make sense of the C++ code.

    @Charles_Sanglimsuwan I was thinking of switching to LWRP for performance and I'd have to reattach all the shaders anyway. Is that something you recommend if I'm going to audit all materials anyway?
     
  9. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    I would tend to agree. Could you file a bug report?

    Let me see if I can cook something up for you.
     
  10. Ayrik

    Ayrik

    Joined:
    Aug 31, 2008
    Posts:
    430
    So, Xbox Live didn't work in XAML mode so I couldn't test it (also mouse cursor exists but I assume that's easy to remove). I'm building a test project now to submit as a bug report.
     
  11. Charles_Sanglimsuwan

    Charles_Sanglimsuwan

    Unity Technologies

    Joined:
    Feb 10, 2017
    Posts:
    69
    I do think that would be a good move.
     
  12. Ayrik

    Ayrik

    Joined:
    Aug 31, 2008
    Posts:
    430
    OK, so it turns out that I had a shader variant collection preloading, and since it was in a different place than "Always Included Shaders" and collapsed, I missed it. This is a misunderstanding I had with shader variant collections, which seems to me need some sort of better explanation somewhere. Anyway, what I've done is follow Charles' advice and remove that and add it to my first scene where I'm manually warming them up with a static loading screen after the UI graphic has a chance to load. So the only "blackness" between splash screens is to compile the shaders necessary for the UI.

    This is an acceptable solution but there are 3 issues here:

    1. (Case 1124823) Blackness between system/app splash screen and Unity splash screen in D3D mode. This does not happen in XAML mode, which "correctly" (sort of, see below) shows the extended splash screen. I've submitted this bug.

    2. (Case 1124827) In XAML mode, the extended splash screen stretches my splash screen to full screen. It should not do this and should emulate the behavior of the OS by centering it based on the scale of the device's screen and DPI.

    3. (Not really a bug, but) Warming up the shaders is blocking, so I can't have an animated loading screen, which is kind of a bummer, but better than a black screen.

    Anyway, thank you SO much for all your help!
     
    Peter77 likes this.
  13. snair692

    snair692

    Joined:
    Feb 2, 2016
    Posts:
    36
    This post also helped me, was experiencing super long screen load on XBOX build but didnt' realize it was the shader variants.

    In my case I am using amplify shader so using the scriptable render pipeline is not an option but I think I have cleaned it up by reducing the pre-loaded variants.

    Thanks for the input!
     
  14. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,674
    Thanks for the bug reports!