Search Unity

Force Terrain LOD regeneration with Experimental Terriain API

Discussion in 'World Building' started by CityGen3D, Mar 9, 2019.

  1. CityGen3D

    CityGen3D

    Joined:
    Nov 23, 2012
    Posts:
    682
    I've been re-writing some of the CityGen3D heightmap generation code to make use of the faster GPU processing with the new Terrain API.

    For instance modifying heightmap using TerrainPaintUtility.BeginPaintHeightmap and calling TerrainPaintUtility.EndPaintHeightmap (and the code in between).

    Note that this is done in the background without direct user interaction, so they are not painting on the terrain directly.

    Everything seems to work fine aside from that the Terrain LOD mesh doesn't get rebuilt when I've finished.
    This means that I'm left with a super hi-res heightmap with no LOD.
    I know this because it's easy to see if you turn on the wireframe in the SceneView as well as the obvious frame rate drop when trying to run it.

    I'm aware that traditionally TerrainData.SetHeights would trigger a terrain LOD rebuild. I've tried calling GetHeights and then SetHeights to manually trigger a LOD rebuild, but this just performs an Undo on whatever I did with TerrainPaintUtility (presumably because at this point the height data stored in there hasn't been updated with the changes).

    So the big question is how can I get Unity to rebuild the terrain LOD after a EndPaintHeightmap call?
    I suppose I'm looking for something like TerrainPaintUtility.RebuildLODMesh but I cant find anything.

    In fact the only way I've found to trigger it is by deselecting currently selected terrains, selecting a different one, then deselecting it. This does then force a LOD rebuild on all terrains.

    This process happens automatically when users are using the built-in Terrain Inspector so there must be a way of doing it internally that Unity calls, but do we have access to it, or could it be added to the API if its needed and I'm not just missing something?

    Thanks!
     
    Skaltum likes this.
  2. wyattt_

    wyattt_

    Unity Technologies

    Joined:
    May 9, 2018
    Posts:
    424
    Try calling


    Code (CSharp):
    1. Terrain terrain;
    2.  
    3. // ...
    4.  
    5. // if on 2018.3 (this call will be deprecated in futures version)
    6. terrain.ApplyDelayedHeightmapModifications();
    7. // or the new call (might only be 2019.1+. I'd have to check)
    8. terrain.terrainData.SyncHeightmap();
    9.  
    GetHeights and SetHeights doesn't work because, as you hinted, the modified heightmap data is still only on the GPU
     
    Skaltum and CityGen3D like this.
  3. CityGen3D

    CityGen3D

    Joined:
    Nov 23, 2012
    Posts:
    682
    Thank you very much!
    ApplyDelayedHeightmapModification seemed to do the trick for me in 2018.3
    SyncHeightmap must be 2019 as you suggested, I couldn't see it in the API, but will switch over to it when I move to 2019.
     
    Skaltum likes this.