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

Bug HDRP Team: Have have an "<Unnamed Pass 0>" problem

Discussion in 'High Definition Render Pipeline' started by dgoyette, May 27, 2023.

  1. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,193
    Short version:

    In current versions of HDRP (possibly SRP), materials will not have correct shader pass data in the first frame upon entering Play mode, or the first frame upon starting a Build. Any code that relies on materials having specific passes is unreliable when called at this time.

    There have been at least two cases where HDRP developers appear to be unaware of this, and are accessing shader passes at unreliable times.

    Until the underlying issue is fixed, or safeguards are put in place, I expect more problems like this to arise.


    Long Version:

    I don't know how long this has been the case, but it seems like a "relatively" recent regression (some number of months). The main underlying issue is that during the first frame upon entering Start, or the first frame that a build runs, Materials do not yet have their proper shader passes. Place this code in a Start/Awake function where you have access to a material:

    Code (CSharp):
    1. for (int i = 0; i < material.passCount; i++)
    2. {
    3.     Debug.Log($"  {i}: {material.GetPassName(i)}");
    4. }
    Enter Play mode, and you can expect to see that the material has a single ShaderPass, and its name will be "<Unnamed Pass 0>". Any calls to
    material.FindPass
    will fail, because the material does not have any valid passes yet. Wait a frame, and suddenly the material will have the correct passes. Note that this isn't restricted to runtime instantiated materials. This is for all materials, global materials.

    I reported this as a bug: UUM-33303 (https://forum.unity.com/threads/in-...play-mode-yields-only-unnamed-pass-0.1421874/) It was closed immediately, and I was told this was the workaround I should follow:

    There are various problems with that workaround. But perhaps the most poignant one is: Unity's HDRP Team isn't following that advice, and they're blindly calling
    material.FindPass
    without checking whether the render pipeline is in place, and that the material has valid shader passes. This has resulted in at least two bugs so far that I'm aware of.
    The point here is that both of these bugs are in Unity's code, because even the Unity developers are unaware of the problem of trying to access shader passes on materials on the first frame after entering Play mode. That's just two bugs I know of (the first has been patched at this point, but the second has not, so the first was not fixed in a globally useful way.) But material.FindPass is used throughout HDRP, and I would expect there are more cases of it being used incorrectly.


    There seem to be two paths to fixing this. One is good, and the other is pretty terrible.
    • Path 1: Fix the underlying issue with trying to access shader passes on the first frame when entering play mode. Fix that, and all the other issues go away.
    • Path 2: Don't fix the underlying issue, but go around "fixing" all the places that you're calling
      material.FindPass
      in HDRP's code. To follow the advice I was given by Unity, that means detecting that the render pipeline isn't ready, and postponing any calls to
      material.FindPass
      by a frame. I think you'll find this is kind of a nightmare, which causes all sorts of downstream issues where now other things break because they assumed that things would be in a valid state by at least the second frame.
    If you go with the second approach, please be aware of how much of a burden this places on people like me who are simply using HDRP, not developing it. It means I can no longer use normal Unity functions like Start/Awake in a way that I expect. Instead, I need to initialize things in coroutines that need to wait a certain amount of time because it can reliably access the materials. It's a total pain.

    But this leads to the even bigger question: So far, this has all been limited to discussing
    material.FindPass
    being unreliably on frame 0. What else is unreliable? It is really just the materials that aren't set up properly? Or are there a slew of other things I'm likely to find also aren't ready when Start is called?
     
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,193
    This still seems to be the case as of LTS 2021.3.30. Not sure if this will ever be addressed, or what the guidance is.