Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Instanced shader output correct/independent in preview, wrong/duplicated in scene render

Discussion in 'Shaders' started by NNSkelly, Mar 24, 2021.

  1. NNSkelly

    NNSkelly

    Joined:
    Nov 16, 2015
    Posts:
    35
    I'm being called to proof-of-concept hoist an old Unity 2018 demo into Unity 2019+ and have encountered a perplexing issue with a custom shader material.
    The content on the pictured planes is the result of a (3rd party quasi-blackbox) monochromatic density fluid sim. The shader maps the value levels in that fluid to a specified color gradient. Specifically, to achieve fully variably-chromatic fluid, I rigged a hack to run 3 sims in parallel, one with value intensity mapped to the red channel, 1 to green, 1 to blue, and hacked the final render shader to use an addative-by-alpha blend (Blend SrcAlpha One). That is all background info, not the issue, merely to illustrate that "just write a new shader to ..." or "y'know you shouldn't be using additive with alpha anyway just Blend One One and use black for transparent" or similar aren't really relevant comments.
    The ISSUE is that in Unity 2018 this worked like a charm, but in Unity 2019, the "red" plane has the red content in the material preview and renders the red content in the scene.
    upload_2021-3-24_15-0-10.png
    The "green" plane has the green content (basically empty; the composite RGB color here is in the magenta range) in the material preview and... renders the red content in the scene.
    upload_2021-3-24_15-9-51.png
    The "blue" plane has the blue content in the material preview and... yup, renders the red content in the scene.
    upload_2021-3-24_15-0-29.png
    At first I thought this was something funky that happened as a result of e.g. HDRP breaking the ability to consistently use dstFactor in Blend declarations, so I separated the planes out as pictured, and no, the additive blend is working just fine, it's just blending 3 instances of the same final output. Which plane is used seems fairly arbitrary, likely a function of render order. When spaced out as above, the red result shows on all, when the 3 systems are coplanar, the blue result is shown on all.
    But clearly Unity knows what the material SHOULD look like... it's just not rendering with it in the scene.
    I'm guessing this is some new happy friendly automatic optimization implicitly sharing buffers across material instances, but I'm at a loss for where to go to tell it NOT to do so. The fact that the independent planes clearly have independent instances with correct independent results in preview suggests that the shader inputs are properly differentiated, not a use case to try [PerRenderData] breakout. So... I guess if anyone knows what the final "output buffer" for a given material instance is called and how to prevent it being shared across instances in the scene/game view, that would be useful.
     
  2. NNSkelly

    NNSkelly

    Joined:
    Nov 16, 2015
    Posts:
    35
    ...even weirder, I just tried the first intuitive stopgap of creating 3 independent material assets all pointed at the same shader code. Now, the red plane (original material) seems to finally be independent, but the green plane (material copy 1) and blue plane (material copy 2) remain inexplicably linked, with the blue plane clearly showing the green content in render but blue content in preview (composite material here is in the cyan/teal range)
    upload_2021-3-24_15-33-57.png
     
  3. NNSkelly

    NNSkelly

    Joined:
    Nov 16, 2015
    Posts:
    35
    One stopgap- harder in 2019+ than 2018- appears to be creating 3 different versions of the original .shader file, hardcoded to different render queues. If this had NOT worked, I would have been mightily confused how the render system was sharing data across passes, but it nonetheless feels excessive for what ought to be able to be multiple independent instances of the same effect.
    Also, for reference, "Enable GPU Instancing" does nothing to fix the issue.