Search Unity

Requesting example for writing heights to Terrain via heightmapTexture or TerrainPaintUtility

Discussion in 'World Building' started by isaac-ashdown, May 7, 2019.

  1. isaac-ashdown

    isaac-ashdown

    Joined:
    Jan 30, 2019
    Posts:
    69
    I'm having trouble using the (hopefully faster) API that sets heights on a Terrain object. Some code examples would be really wonderful on how to go about it. No matter what I have tried, the resulting heights just get set far above the maximum height for the Terrain, and are all flat. Here's some example code:

    Code (CSharp):
    1. Terrain terrainComp = forTerrainComps[tx, ty];
    2. var renderTex = terrainComp.terrainData.heightmapTexture;
    3. Texture2D tempTex = new Texture2D(renderTex.width, renderTex.height, UnityEngine.Experimental.Rendering.GraphicsFormat.R16_UNorm, UnityEngine.Experimental.Rendering.TextureCreationFlags.None);
    4.              
    5. var rawData = tempTex.GetRawTextureData<short>();
    6.  
    7. for (int i = 0; i < rawData.Length; i++)
    8. {
    9.      rawData[i] = 0;
    10. }
    11.  
    12. Graphics.CopyTexture(tempTex, renderTex);
    13. terrainComp.terrainData.UpdateDirtyRegion(0, 0, renderTex.width, renderTex.height, true);
    This code definately does something - it makes the terrain heights be placed at least twice as high as the maximum height that the terrain has specified (similar to this post, but I wasn't able to ever get it working). Note that the target texture is being set to all zeros, but whatever numbers i try in there I get the same result.

    My ultimate goal is to use NativeArrays that are filled via Burst jobs, as requested here.

    I also tried using the TerrainPaintUtility, but with essentially the same results, except that I have no idea what to pass in for 'boundsInTerrainSpace', as terrain space isn't defined, and so it only impacts a subset of the terrain. Also, as that API includes things like 'undo tags', it makes me think it's not supposed to be used at runtime, but rather only in the editor.

    I note that there are more APIs available in 2019.2 (as detailed here), but we're unable to go to 2019.1 or .2 due to this issue.
     
  2. isaac-ashdown

    isaac-ashdown

    Joined:
    Jan 30, 2019
    Posts:
    69
    OK, worked it out:

    - the native array should be <ushort>
    - need to call tempTex.Apply() after

    Works now - and initial tests show its definately faster, hooray!
     
    alemnunez likes this.
  3. YetAnotherKen

    YetAnotherKen

    Joined:
    Jun 17, 2019
    Posts:
    30
    Thank you for keeping this thread up-to-date, I have been learning a fair amount from it.
     
  4. iddqd

    iddqd

    Joined:
    Apr 14, 2012
    Posts:
    501
    Hi @isaac-ashdown

    I was referred to this post from here:
    https://forum.unity.com/threads/und...rendertexturetoheightmap.706679/#post-4733171

    I'm happy to see that others are trying to speed up procedural terrain generation.

    It seems like what you're doing is the same that the new CopyActiveRenderTextureToHeightmap does. However the issue is that Unity still needs to readback from the RenderTexture to the CPU and that is still the slow part.

    You mentioned here:
    https://forum.unity.com/threads/terraindata-api-nativearray.662620/
    That you need to call terrainComp.ApplyDelayedHeightmapModification(); and that is where the GPU heighmap gets copied back to the CPU and I haven't found a way to speed this up.
     
  5. isaac-ashdown

    isaac-ashdown

    Joined:
    Jan 30, 2019
    Posts:
    69
    Hi! I'll reply there as I see you got a dev's attention :D
     
    iddqd likes this.
  6. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    660
    Not wanting to necro this thread, but did anyone figure out the ideal performance path for creating terrain from height values, with minimum delay and processing overhead?