Search Unity

Question How to manage grass in a top down game

Discussion in 'Scripting' started by shuskry, Mar 26, 2023.

  1. shuskry

    shuskry

    Joined:
    Oct 10, 2015
    Posts:
    462
    Hello everyone :D

    I'm trying to find the best and optimize way to render some grass on my 3D game.
    I'm trying to optimize it at the maximum because of trying to build for mobile :)

    My game it's a top down game, So I know that I haven't to render a landscape with grass and other complicated things.

    The problem is even with a small map , adding grass ( 3200 grass patch) , increase my drawcalls ...
    There is a maximum of 150-170 grass patch visible at one time by the camera for a maximum of 7K tries and 13k vertex.
    All patchs have the same material/shader

    Here a screen with grass only enable on the camera view ( set to static batching):
    upload_2023-3-26_3-13-12.png

    Here a other screen with all the grass enable on the 100*100 map:
    upload_2023-3-26_3-18-7.png

    Like you can see, I have 4 more draw calls , but I don't understand why :/
    the limit of vertice with static batching is 64K no?

    Is it the good way to render grass ? Can I do something else to render better my grass on mobile?

    thanks for helping me , Have a good day :D !
     
  2. QuinnWinters

    QuinnWinters

    Joined:
    Dec 31, 2013
    Posts:
    494
    One option, despite it being 3D, is to use 2D grass sprites that always face the camera. Then you could have multiple different animated grass types from one sprite sheet and regardless of how many of them you have on screen at once it's only one draw call.
     
    shuskry likes this.
  3. shuskry

    shuskry

    Joined:
    Oct 10, 2015
    Posts:
    462
    Thanks for your answer !

    It's already what I'v done ^^
    It's a top down Game like diablo, so the camera angle/Rotation doesn't move , and my grass are only some square facing the camera with a sprite texture on it . All grass patch are the same in the example but I have a atlas for this texture to have multiple grass ...
    It's URP lit shader to receive shadow and all grass patch don't cast shadow

    But the problem still here with this solution...

    After investigate with the Framerate Debugger, I notice that Unity combine all these grass in 5 different combined mesh:
    upload_2023-3-26_16-41-52.png

    And like you can see , the grass are combined randomly, this is why my draw calls are increases ...
    So on my second screenshot with all grass enabled, some grass patch are combined with grass outside the screen....

    how I can avoid that ? I'm pretty sur that is not the good way to go no? Maybe I can divide my scene in some square , and calculte the distance with the player from there , and enable/disable them when the distance is correct or not?
     
  4. QuinnWinters

    QuinnWinters

    Joined:
    Dec 31, 2013
    Posts:
    494
    There are probably lots of ways of going about it, but my go-to method in situations like this is to use a trigger collider on the camera that's the size of the view area and have the grass objects tagged. Then use a combo of CompareTag, layers, and Physics2D.IgnoreCollision so that the trigger only sees the grass and uses as little overhead as possible. Then it's just a matter of deciding what to do with them when they enter or exit the trigger. In your situation it might work best to deal with the grass in a grid of groups rather than individually, and turn entire groups on or off.

    You may also want to look at GPU Instancing and Occlusion Culling.
     
    shuskry likes this.
  5. FrankvHoof

    FrankvHoof

    Joined:
    Nov 3, 2014
    Posts:
    258
    shuskry likes this.
  6. shuskry

    shuskry

    Joined:
    Oct 10, 2015
    Posts:
    462
    Thanks for your help :) I succeeded with manualy combined meshes ^^

    have a good day :)