Search Unity

How to get unity_ObjectToWorld in statically batched objects?

Discussion in 'Shaders' started by SomeHumbleOnion, Aug 24, 2021.

  1. SomeHumbleOnion

    SomeHumbleOnion

    Joined:
    Jan 18, 2021
    Posts:
    28
    Hello friend!

    I've been trying out different optimization techniques for my game lately and static batching has been the absolute best when it comes to reducing draw calls and bumping up my FPS. The only problem is I can't statically batch any of my foliage objects because they have a custom wind shader (written by Nicrom) that uses unity_ObjectToWorld to simulate the wind. Since all the foliage is statically batched, the world position is incorrect for each object so the shader basically breaks.

    Is it possible to get the individual world positions of the objects that are batched statically so that the vertex function in my wind shader still works? Thanks for the help!
     
  2. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,550
    No, that information is lost as all those leaves essentially become one big mesh with a single pivot. It's a very fast merge that just packs the mesh data arrays together.

    The world position should still be correct though. It is likely some other function of the shader that is broken due to the batching. If world position was incorrect, then the objects wouldn't even be rendering proper at all for any statically batched objects in Unity.

    One option would be to bake the world position into the leaves' vertex color (or a secondary UV channel if you're utilizing vertex color already) when the tree is placed into the world. Then your wind shader can be modified to just grab that value.
    This will also create some overhead though and result in every leaf having unique mesh data in the scene... which could blow up memory. But I believe Static Batching already does this anyways and why the documentation even recommends against doing it for trees somewhat.

    A better option though might be to look into simply using GPU instancing, that's kind of an ideal use-case there.
     
  3. SomeHumbleOnion

    SomeHumbleOnion

    Joined:
    Jan 18, 2021
    Posts:
    28
    Thanks for the reply! That makes sense then. I was also recently told about this method of baking the position into the vertices, but yeah that sounds like a lot of overhead especially when I'm trying to statically combine a ton of foliage objects that have this wind shader.

    The weird thing is GPU Instancing drops my FPS dramatically when I enable it on my material. Although it saves some batches, it raises my CPU and render thread and drops the FPS by at least 80 frames or so (I go from like 500 to 420ish). And this is just me doing it for one material, I've got a lot of different foliage in game with their own materials as well. It's a shame because GPU Instancing sounds like the key to my solution but I'm not sure why it's performance is so poor with my game. I've heard other devs complain about their FPS dropping with GPU Instancing as well but no one has explained why so I'm assuming it just depends from project to project?
     
  4. SomeHumbleOnion

    SomeHumbleOnion

    Joined:
    Jan 18, 2021
    Posts:
    28
    For reference, I took a screenshot of an area in my game with a heavy amount of my low poly foliage. On the left I have GPU instancing enable for their materials which puts me at 190fps and on the right I have it disabled putting me at 260fps. If I remove my wind shader from these materials (making them completely static) and use static batching on them instead, my performance shoots up tremendously. It's really unfortunate that the wind shader won't work with it.
    Instancing Enabled.PNG Instancing Disabled.PNG