Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Feature Request What's the fastest way to get multiple terrain heights on multi tile terrain?

Discussion in 'World Building' started by Rowlan, Dec 2, 2022.

  1. Rowlan

    Rowlan

    Joined:
    Aug 4, 2016
    Posts:
    3,309
    I'd like to shape a river automatically and hence sample the height around given world positions. However for one GetHeight and GetHeights are super slow. And for the other those methods don't consider multi tile terrain.

    A proper API for this rather common problem coming from Unity would be nice :)
     
  2. wyattt_

    wyattt_

    Unity Technologies

    Joined:
    May 9, 2018
    Posts:
    411
    Heya! I can suggest a non-proper API for this haha. But to answer the question in the post title:

    If you're getting points from a bunch of different Terrain tile heightmaps at once, you could bind them to a compute shader with a Texture2DArray of all affected Terrain textures, a StructuredBuffer<float2> for _TerrainUVs and StructuredBuffer<int> _TerrainIDs to represent your sample points. Then write to a RWStructuredBuffer<float> _Heights. This would process them all in parallel. Then you'd called GetData on your _Heights ComputeBuffer to get the height values.

    I'm not actually trying to implement this but this would probably be my first attempt for the compute shader:

    Code (CSharp):
    1.  
    2. Texture2DArray<float> _TextureTiles;
    3. StructuredBuffer<uint> _TileIDs; // indirection index into the Texture2DArray
    4. StructuredBuffer<float2> _UVs;
    5.  
    6. RWStructuredBuffer<float> _Heights;
    7.  
    8. SamplerState sampler_BilinearClamp;
    9.  
    10. [numthreads(256, 1, 1)]
    11. void GetHeights(uint3 id : SV_DispatchThreadId)
    12. {
    13.     uint index = id.x;
    14.     uint tileID = _TileIDs[index];
    15.     float2 uv = _UVs[index];
    16.     float height = _TextureTiles.Sample(sampler_BilinearClamp, float3(uv, tileID)); // this probably isn't 100% correct
    17.     _Heights[index] = height;
    18. }
    19.  
    Then your Dispatch call would be something like

    Code (CSharp):
    1. cs.Dispatch(mathf.ceil(uvs.Length/ 256f), 1, 1);
     
    Last edited: Dec 3, 2022
    Rowlan likes this.
  3. IndieForger

    IndieForger

    Joined:
    Dec 31, 2012
    Posts:
    92
    What does
    [numthreads(8, 8, 8)]
    do exactly?
     
  4. wyattt_

    wyattt_

    Unity Technologies

    Joined:
    May 9, 2018
    Posts:
    411
    [numthreads(8, 8, 8)] would mean that each thread group that is spawned via the Dispatch call will have 8 x 8 x 8 threads (512 in total)

    I just changed it to [numthreads(256, 1, 1)] since you'd actually only need to sample once for each lookup point, so a 1-dimensional thread group is sufficient for this. I had 8 x 8 x 8 before because I had full texture samples in mind for each heightmap texel but that wasn't correct

    Here's the Microsoft documentation for numthreads: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-attributes-numthreads
     
    Rowlan and IndieForger like this.
  5. wyattt_

    wyattt_

    Unity Technologies

    Joined:
    May 9, 2018
    Posts:
    411
    With the 256 x 1 x 1 example, you'd pretty much be spawning groups of 256 threads and each thread in those groups is used to sample the height for one of the points in your array (ie your spline points)
     
  6. IndieForger

    IndieForger

    Joined:
    Dec 31, 2012
    Posts:
    92
    Thank you @wyattt_ for both an explanation and the link.
     
  7. wyattt_

    wyattt_

    Unity Technologies

    Joined:
    May 9, 2018
    Posts:
    411
    Np. Let me know if you've got other questions about it
     
  8. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,360
    Wouldn't your dispatch call be for the number of UVs (uvs.Length), not the number of terrain tiles / 256? You want one thread per height lookup, not some fractional amount based on how many terrains there are.
     
    wyattt_ and Rowlan like this.
  9. wyattt_

    wyattt_

    Unity Technologies

    Joined:
    May 9, 2018
    Posts:
    411
    Yes! You're correct. I will edit that. Thanks @jbooth