Search Unity

Bug Shaders lose ComputeBuffer Binding after (any) Shader is edited/recompiled

Discussion in 'General Graphics' started by Arthur-LVGameDev, Jul 21, 2022.

  1. Arthur-LVGameDev

    Arthur-LVGameDev

    Joined:
    Mar 14, 2016
    Posts:
    228
    I've searched quite a bit on this issue, found one old (multiple years) post on it, but really nothing else.

    ISSUE
    When editing a (any) shader in our project, all of our custom shaders lose bindings to ComputeBuffers that they utilize for data transport.

    This makes debugging, tweaking, and writing these shaders really difficult because there does not appear to be *any* way to force re-binding of the buffers -- meaning the only way to test shader changes is to exit & re-enter Play Mode.

    This is also made even more frustrating because the buffer bindings are lost when any shader in the project is edited -- not only when the instancing shader(s) themselves are edited. This means that editing any shader in our project causes us to "lose rendering" for anything that uses a custom shader which relies on ComputeBuffers for data transport. In this particular project it's pretty problematic since the vast majority of our "high-volume" rendering is being handled via similar approach.

    DETAILS
    • Pseudo-ish code here:
      https://gist.github.com/ArthurD/37e14c81eb257f8c3f4bd42cf2fdae4c

    • Unity Version: Currently on Unity 2021.3.6f1 -- but I think it's been a problem as far back as 2019.x
    • Render Pipeline: Built-in render pipeline
    • Platform: Reproduces on macOS and Windows.

    • Few things I've tried:
      • Checking if buffer is bound (see code); the method returns true (binding exists) no matter what.
      • Forcibly rebinding the buffer every frame (see code); issue persists.

    • Warning on macOS/Metal - it will (sometimes?) throw a warning along the lines of:
      "Shader expects buffer at line X but none bound - stopping draw call to prevent crashes."

    • Misc. Thoughts & Why it *seems* like a bug:
      In cases where we use similar techniques but instead utilize Textures for data transport, the texture bindings are not lost after shader edits/shader compilation -- which is what makes me think this is a bug.

      If the bindings DO *have* to get lost, that could be totally understandable -- but I'd expect that there would be a way to "forcibly" re-bind the buffers, even if it's just via temporary editor-only code for quick testing, etc.

      And then, perhaps I'm doing something totally and/or obviously wrong -- if that's the case, I'd love to know what, it'd definitely make life easier! =)


    • BONUS - Shader Syntax Highlighting in VS for Mac (2022 + prior versions, too)
      This drives me bonkers; can we get this fixed, please? It's been an issue ever since Unity switched the default macOS IDE to VS, and the issue continues to persist in both the non-preview VS that Unity ships with as well as the latest ("preview"/VS 2022 for mac) version, too.

      Screenshot: https://imgur.com/a/1JDVXox
      The comment highlighting is bugged when using "//" for line comments in shader files -- it will 'blur'/have 'comment appearance' for the commented-out line AND, in at least some (semi-low but non-deterministic/variable) percentage of cases, for the next line, too!! It drives me nuts & the only "workaround" is to use "/* comment */" syntax instead (sometimes it'll comment-blur the next two lines, even) -- else, to find a custom extension (one is available for windows VS, but not VS-for-mac) that actually handles .shader files properly. /bonus-rant =D
     
    Last edited: Jul 21, 2022
  2. georgerh

    georgerh

    Joined:
    Feb 28, 2020
    Posts:
    72
    AFAIK, when reloading shaders, materials have to be serialized and deserialized. Every binding that is not a property is lost. So you can work around that problem by creating hidden properties but unfortunately, not every parameter can be a property (e.g. there are no matrix properties). Don't know if there is a property for compute buffers.

    Only other workaround I'm aware of is to set them every frame in the editor.
     
  3. Arthur-LVGameDev

    Arthur-LVGameDev

    Joined:
    Mar 14, 2016
    Posts:
    228
    This would be totally fine & a fully acceptable workaround for development purposes, for sure. Unfortunately, it still doesn't work -- issue persists even when re-binding the buffers every frame.

    Additionally, the Material.HasBuffer method continues to return true (no matter what; whether re-binding them every frame, and even if only binding them upon startup and not re-binding them -- it still returns true regardless).
     
  4. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    726
    We have this same problem, but for us it works to rebind every frame (just in the Update() method of a script that has [ExecuteAlways] ). So not sure what would cause it to be different for you.
     
  5. grizzly

    grizzly

    Joined:
    Dec 5, 2012
    Posts:
    357
    Bindings are lost when compiling shaders in the Editor. Until this is fixed my work around looks something like this:
    Code (CSharp):
    1. #if UNITY_EDITOR
    2.  
    3. void OnApplicationFocus (bool focused)
    4. {
    5.     if (focused)
    6.     {
    7.         BindBuffers();
    8.     }
    9. }
    10.  
    11. #endif
     
    MaxEden and richardkettlewell like this.
  6. mahdiii

    mahdiii

    Joined:
    Oct 30, 2014
    Posts:
    856
    Even when importing new assets, rename files in the project, delete, etc. it loses compute buffer value.
    I handled it with an editor script to bind it again when the project changes