Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Performance problem when creating terrains at runtime

Discussion in 'Scripting' started by mrtkhosravi, Apr 2, 2015.

  1. mrtkhosravi

    mrtkhosravi

    Joined:
    Nov 9, 2014
    Posts:
    198
    I am creating terrains dynamically at runtime. I split the workload of calculating heightmap and splatmap with corountines and everything is going smooth except when I use TerrainData.SetHeightmap() and that creates a nasty 60ms spike on my computer. My project is targted for mobile devices so this figure will be far higher on device. My terrains have 513 heightmap and 512 splat and basemap. Here are the things I tried:

    1. Called SetHeights in 16 chunks every time updating a portion of the terrain. The spike reduces to 26 on PC. Still very high to consider and it has to be run 16 times!
    2. After instantiating terrain disabled terrain collider and even DestroyImmediated it. Then tried to set heights. No difference.
    3. Called the internal method SetHeightsDelayLOD via reflection. It actually reduces the time to 12ms for the whole terrain and effectively solving my problem but also disables the terrain LOD system and leaving me with millions of vertices.
    4. Tried to bypass unity thread safety check with no luck.
    5. Made my terrain 2048 and also made their width and height 4X larger. This will increase the interval between 2 hiccups and make the game more playable but again it has its problem as I have to load a huge square of terrains around my player and on my tests that eats the memory 3 times the 512 case and would bring every mobile on the market to its knees.
    6. Made terrains 128 and the camera render time goes crazy high.
    7. Went through asset store for an alternative for unity terrain engine with no luck.
    I'm also curious about how unity terrain editor works because it appears to run more smoothly than if it would call SetHeights.

    This is a serious issue that if solved can open the door to more interesting dynamic worlds and destructible terrains. Any ideas?
     
    Last edited: Apr 2, 2015
  2. ObviousDWest

    ObviousDWest

    Joined:
    May 20, 2013
    Posts:
    5
    Turn off Tree Colliders. Made a big performance difference for me.
     
  3. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    SetHeights is an expensive call. I'm attempting to build the asset you are asking for, but as yet I have found no way around the SetHeigts limitation. Best performance I have so far is to split the individual SetHeight calls across several frames via a coroutine. My general understanding is that this will have to wait until the new terrain system is rolled out.

    PM me if you are interested in looking at the asset.
     
  4. Sir-Spunky

    Sir-Spunky

    Joined:
    Apr 7, 2013
    Posts:
    132
    Hi. I have the exact same problem as you, which is really frustrating. Did you manage to find a solution?

    Regarding method 3, according to http://docs.unity3d.com/ScriptReference/TerrainData.SetHeightsDelayLOD.html you have to call Terrain.ApplyDelayedHeightmapModification manually to update LOD information. Did you try this? (I've not yet tried this method as I didn't know about reflection)
     
  5. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
  6. Pavlon

    Pavlon

    Joined:
    Apr 15, 2015
    Posts:
    191
    I can't tell you how to do it but i think tesslation could solve the problem.
    Or some other fancy vertex shader...