Search Unity

Bug in SRP batching for shadowmap or am I misunderstanding something?

Discussion in 'General Graphics' started by najati, Jan 9, 2020.

  1. najati

    najati

    Joined:
    Oct 23, 2017
    Posts:
    42
    Hi!

    I seem to be bumping into something I don't understand or a bug in batching. My actual use case is more complex than this, of course, but I wanted to make the smallest complete example that showed what I was seeing.

    The batcher seems to work for me when rendering opaques, but they aren't being batched for the shadowmap like I'd expect. Here's what I did:

    The repo for the play-a-long: https://github.com/najati/UnityRenderTest/tree/master.
    Screens for the different versions:
    screens.png

    Set up a simple LWRP project:
    • Started with LWRP template in Unity 2019.2.16f1 (the version I'm using for my actual project).
    • Removed everything from scene, deleted unused assets. Played with the skybox settings for funsies.
    • Created a ground quad. Created a material for it, assigned it the simple lit shader
    • Created two floating quads. Created a material for them with the simple lit shader
    This is commit 0d82b58 in the repo. At this point, frame debugger has a bunch of stuff in it from MSAA, etc, and nothing is batched, as expected.Looks like left screenshot. All as expected.

    0d82b58.png

    Next I cleaned up the frame render:
    • Deleted other LWRP setting assets
    • Disabled MSAA/HDR
    • Enable SRP batching
    This is commit ef8e905, and has a simpler render frame, as expected. Still looks the same, basically.

    ef8e905.PNG

    Next I made the shader fancier:
    • Create shader graph w/ material, assigned to floating quads
    • Created hole in quads with the shader graph via alpha clipping
    • shader graph.png
    This is commit bcc7d7c. It works as expected, no changes in shader graph. Middle screenshot, you can see the holes.

    Next step is where I get confused.
    • Create a small script attached to the floating quads.
    • The script changes the color and hole size on the floating quads
    This is commit 15cde93. It looks like you'd expect, as seen in the right most screenshot. The quads are batched together for the render opaque pass, but not for the shadowmap pass. There are three batches, one each for ground, right quad, left quad.

    15cde93.png

    None of these had and effect on anything:
    Opened project in 2019.2.17f1
    Opened project in 2019.3.0f3
    Upgraded to the latest URP.
    Opened project in 2020.1.0a18

    I'm confused about why the batcher seems to be happy to batch the quads for opaque rendering, but not for the shadowmap, but only if the properties are different. The only reason I could come up with is that they each need to effect the shadowmap independently, but that would still be the case even if the holes were the same size so that doesn't seem to be the case.

    I looked at the generated shader code but couldn't see anything in the shadowcaster pass that would prevent batching when it was working for the opaque pass. Admittedly, I'm not an expert in that area!

    I've also tried an approach using GPU instancing, and it seems like I was making progress, but Unity seems to be trending towards the SRP batcher, and it seems like it should work well for my actual use case. Also, enabling the SRP batcher seemed to preempt GPU instancing, even if it was turned on for the materials, so it seemed like I couldn't mix the two.

    In my actual use case I have way more than two of these quads with holes and a number of other simple lit meshes and would love to maintain decent shadows. Also, we're targeting mobile initially. Any input would be greatly appreciated - thanks!
     
    Last edited: Jan 9, 2020
  2. najati

    najati

    Joined:
    Oct 23, 2017
    Posts:
    42
    Short update:

    I changed the shader to read the radius from a UV and updated the little script to place the radius in the UV instead of the material properties. After doing this, the calls are again batched in the shadowmap pass, even with the different hole sizes.

    If the SRP is doing transforms on the CPU and uploading a combined mesh to the GPU every frame (I believe that's how it works), then maybe putting extra data in the UVs is okay, performance-wise if I'm changing that data every frame, but it still seems like if this works, then I should be able to convince the shadowmap pass to be happy with the material property and still batch.