Search Unity

Unity terrain and grass, CPU spikes in Terrain.Data.BuildPatchMesh

Discussion in 'Editor & General Support' started by DirtyHippy, May 31, 2014.

  1. DirtyHippy

    DirtyHippy

    Joined:
    Jul 17, 2012
    Posts:
    198
    I have been playing a lot in the terrain system the past few days, trying to understand the limitations. At first I implemented some terrain using TerrainComposer + RTP, and it looked great, but there were constant, subtle spikes in the FPS that I could not understand, so I put together a smaller project to test it.

    I have a used a fairly simple single terrain from a height map that I post-processed with terrain composer (without RTP/AFS). Adding grass at any decent constant density with a detail range of 80m will noticeably cause the spikes as you move (presumably as you arrive at the next visible patches) and it just gets worse as you increase the detail distance (presumably because more patches are viewable). Keep in mind that the frame rate when not spiking is at ~250-300fps so clearly it is not a rendering issue as the draw calls/tris are quite low. However, as you move around the world, the spikes seem to occur at frequent intervals - in some cases every few seconds, and in the profiler they come up ~100ms in Terrain.Data.BuildPatchMesh, which is awful. Note: I have tested all of this with standalone builds to remove that as a potential variable as well (still occurs).

    I have played around with all of the settings I can think of (while maintaining a similar grass density), and nothing mitigates it to any major degree (and I wouldn't expect it to as the cost likely scales against the density rather than the patch sizes).

    So the question is - am I missing something? Is no one else seeing this?
     
  2. Brenden-Frank

    Brenden-Frank

    Joined:
    Aug 5, 2012
    Posts:
    110
    You aren't missing a thing. I have a bug report on this: 614962

    Unfortunately grass is not very usable right now if you want any kind of decent frame rate.
     
  3. Brenden-Frank

    Brenden-Frank

    Joined:
    Aug 5, 2012
    Posts:
    110
  4. mbowen89

    mbowen89

    Joined:
    Jan 21, 2013
    Posts:
    635
    Sorry for the bump but Brenden, did you ever do anything to try and get around this the best you could?
     
  5. Brenden-Frank

    Brenden-Frank

    Joined:
    Aug 5, 2012
    Posts:
    110
    After much discussion with Unity there was a checkbox added to the terrain settings called "Collect Detail Patches".

    If unchecked, this makes all the terrain grass precache so that there's nothing being built at runtime. It's worth mentioning however that depending on your terrain size it will consume quite a bit of memory.
     
  6. mbowen89

    mbowen89

    Joined:
    Jan 21, 2013
    Posts:
    635
    Yeah, on my mobile game with decent size forest terrain with lots of details it wouldn't be the best most likely... oh well, I'll just have to optimize everything the best I can then as usual! :)
     
  7. Brenden-Frank

    Brenden-Frank

    Joined:
    Aug 5, 2012
    Posts:
    110
    Your best option is to create custom textures that use 2-3 individual grass pieces to make a wider detailed one. This way you can make your detail meshes wider to cover a larger area and use a much smaller density. The less detail density you have the smaller the build patch mesh hitch.

    The only "gotcha" is that details look noticeably worse on hills. Would be nice if Unity gave the option to make detail meshes angle to terrain normal direction.
     
    twobob likes this.
  8. mbowen89

    mbowen89

    Joined:
    Jan 21, 2013
    Posts:
    635
    Do you know the specifics as to what exactly happens?

    What's the correlation between the number for "Detail Resolution Per Patch", patch collection while walking around, the number or density of billboard grass/detail meshes I paint, etc?
     
  9. Brenden-Frank

    Brenden-Frank

    Joined:
    Aug 5, 2012
    Posts:
    110
    Detail resolution per patch - the higher the number, the more meshes that will be combined into a single mesh. This saves drawcalls but will spike your profiler the larger the mesh it has to build.

    Detail density is how many meshes are closely placed next to each other. The higher this number, the bigger your profiler spike will be.

    Setting both numbers to a high value can be troublesome because unity has a 64k vert max which means that it will break and leave big open holes of details that failed to draw because they couldn't be added to the chunk without exceeding the limit.
     
  10. mbowen89

    mbowen89

    Joined:
    Jan 21, 2013
    Posts:
    635
    OK, and so as you walk around and new details come into view, it's creating those meshes on the fly, which creates the hiccups.
     
  11. Brenden-Frank

    Brenden-Frank

    Joined:
    Aug 5, 2012
    Posts:
    110
    Correct, and it deletes them as you move away to conserve memory. It had good intentions but the execution isn't there.
     
  12. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,172
    It's actually a really bad implementation. It doesn't even take into account distance per say, if you pan around it's loading and unloading the same stuff over and over while not even moving. If they fixed that, which is a silly easy thing to do with a fast spatial hash, this problem would largely disappear.
     
  13. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,172
    So I got around to actually fixing this in my game. It's the tree colliders that are the main culprit not rendering. I had a fast 2d spatial hash in java that I've used a lot so I did a quick port to C#, and am using it to dynamically place/remove colliders on trees as I move around.

    I went from 40fps and constant 200ms+ stutters to 100+ fps and zero stutters.
     
  14. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    1,763
    sharage? Gist? Linkage?

    I hate it when people say "I FIXED IT BRILLIANTLY" but don't share how. :(
     
  15. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,172
    I just posted on this subject in the physics forum and posted the spatial grid I used, minus the code that actually checks the grid every second or so, but that's application specific and not the hard parts.

    http://forum.unity3d.com/threads/terrain-culling-and-colliders-is-hosed.310594/

    Note that the spatial grid might have a bug I haven't found. It's pretty much a direct port of a java implementation I've used for around a year that I know works, but there might be a couple of edge cases as accessors are different so a bit of the flow changed.
     
    twobob likes this.
  16. twobob

    twobob

    Joined:
    Jun 28, 2014
    Posts:
    1,763
    respect and gratitude