Search Unity

Why are my custom grass billboards so much slower than builtin unity grass?

Discussion in 'General Graphics' started by RibsNGibs, Apr 13, 2017.

  1. RibsNGibs

    RibsNGibs

    Joined:
    Jun 17, 2016
    Posts:
    15
    OK, so long story first:

    Billboard grass is really broken looking in VR so I wrote my own grass vert/frag shader that points towards the camera instead of aligning with the forward vector of the camera, and I'm attaching that shader/material to small little planes.

    Weirdly enough my grass would work correctly if there was only one grass object but would fail if there were multiple instances of the grass around (all the grass would get translated to the same location and rotation by the vert shader). I found out that was because of dynamic batching.

    So I disabled dynamic batching on my shader, and now my custom grass looks good and works with VR... but it's quite slow. 5 thousand grass objects and I end up with almost 9000 draw batches and the grass eats up about 80% of the 11ms budget I have per frame (to hit 90fps) which is obviously unacceptable.

    Anybody know what the built-in unity terrain grass magic is and how it renders so fast and how I can reproduce it? If I paint a bajillion bits of unity grass down there are very few draw batches and it renders fast. If I look at the builtin grass billboard shader Unity uses (WavingGrassBillboard.shader), it also does a "DisableBatching"="True", so I don't know what the difference is.

    ...Although if I follow the shader code trail it looks like (I think, maybe) the verts coming in are already positioned correctly so that the quads are facing the camera plane and that the vert shader doesn't do much but add the "waving". Anyway, so I tried making a vert shader that didn't actually move any vertices around so that I could turn batching back on, and added scripts to all X thousand of my grass objects to point them all at the camera, and now my draw batches are back in a sane range but of course now it's running even slower because it has to run Update() on 5000 grass objects and orient them all.

    OK, back to the main question: what can I do to make my billboard grass run faster?