Search Unity

Reducing TerrainData resource loading overhead per frame

Discussion in 'Scripting' started by maxxa05, May 5, 2015.

  1. maxxa05

    maxxa05

    Joined:
    Nov 17, 2012
    Posts:
    186
    In my game, I need to load terrain assets from Resources and Instantiate them in my scene to save memory. I'm loading them asynchronously this way :

    IEnumerator AsyncLoad<TerrainData>(name)
    {
    var request = Resources.LoadAsync<TerrainData>(name);
    yield return request;
    // Terrain GameObject creation code, not the source of the overhead​
    }
    It works, but in the profiler I get a ~300ms synchronous spike from TerrainData.AwakeFromLoad in a single frame. This call contains calls to TerrainData.GenerateBaseMap, TerrainData.GenerateBaseMapSpecularOrMetallic and other lighter methods. No matter what I try to execute over several frames, I can't get rid of that particular spike.

    I guess I could divide terrains even more, but it would take some time and I would get more spikes, but smaller. Is there another way to get rid of it, or at least reduce it?
     
  2. ThatGuyFromTheWeb

    ThatGuyFromTheWeb

    Joined:
    Jan 23, 2014
    Posts:
    29
    Hi ...
    I'm not sure how to get rid of it, but what are GenerateBaseMap and such doing? Those are functions you wrote i assume? And about what terrain size do we speak here?
     
  3. maxxa05

    maxxa05

    Joined:
    Nov 17, 2012
    Posts:
    186
    Those are not functions I wrote, they are internal calls in TerrainData.AwakeFromLoad. Here's a screenshot from the profiler. terrain loading.png

    Each terrain has a 250X250 size, with 2048 of Heightmap Resolution, Detail Resolution, Control Texture Resolution and Base Texture Resolution.
     
  4. ThatGuyFromTheWeb

    ThatGuyFromTheWeb

    Joined:
    Jan 23, 2014
    Posts:
    29
    Ok, i misunderstood that.

    Without beeing an expert on unity terrains, i would say there's not much you could do. At least i had similar problems creating terrains of that size from float arrays. Simply assigning the heightmap, detail data and such directly to the terrain and detail textures was pretty slow with 2048 resolution. I tried a while to work around that, but never found a faster approach, threading didn't really work and so on - so i decided i would probably go with 512x512 maps.

    If you ever find a solution to this, be sure to let me know. :)
     
  5. maxxa05

    maxxa05

    Joined:
    Nov 17, 2012
    Posts:
    186
    Thanks for your input, I tried reducing the resolutions of the different terrain map resolutions and it accelerated the process, but it destroys my terrain's heightmap and splatmap and it still takes too much time to run. I would really like to have some way to make this process run before the terrains are loaded without having to keep the terrains in memory, or to have it run in the background.
     
    Velo222 likes this.
  6. seanybaby2

    seanybaby2

    Joined:
    May 17, 2013
    Posts:
    120
  7. Binary42

    Binary42

    Joined:
    Aug 15, 2013
    Posts:
    207
  8. seanybaby2

    seanybaby2

    Joined:
    May 17, 2013
    Posts:
    120
  9. bartje86tralala

    bartje86tralala

    Joined:
    Aug 1, 2012
    Posts:
    9
    bump

    This is still the case with InstantiateAsync<GameObject> whereby the gameObject contains a terrain with terrainData. When intergrated with the mainthread this terrainData.AwakeFromLoad is still the bottleneck.