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):
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.
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:
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?
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.