Search Unity

Terrain api performance questions/requests

Discussion in 'World Building' started by snacktime, Sep 20, 2019.

  1. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    - Can we get NativeArray api's for getting/setting height/alpha data?.

    - For terrain colliders, are those partitioned in some way? I'm trying to assess if creating our own partitioned collider system would be worth it for runtime height updates. The testing I've done say's yes, but it's impossible to measure accurately. So I guess what I'm after is in theory if we are creating the meshes in jobs and using optimized triangulation, should a partitioned approach with that beat what Unity is doing?
     
  2. crysicle

    crysicle

    Joined:
    Oct 24, 2018
    Posts:
    95
    @snacktime based on my testing, even if there is partitioning done on Unity's end, it's not efficient for constant runtime updates to the heightmap. If you're doing small area updates to a huge heightmap, partitioning is the way to go. I'd go further and say that making your own collision API specificly for the terrain would also drasticly improve performance, simply because you can use the already gathered new data without needing to go through SetHeights() which incurs a high performance penalty to use at runtime or SyncHeightmap() which stall the CPU to wait on the GPU. However, before creating your own libraries, you should consider how big the deformation is at any point during runtime.

    As far as my experience with the terrain API, assigning new 33x33 heightmaps to 33x33 terrain after you have calculated them has a penalty of 0.1-0.2ms on my i7-5820k via SetHeights(). Considering the high ms point, thats about 10k heightmaps for 2ms, or 3k heightmaps for 2ms per 1GHz main core processor speed, since the updates are not multithreaded. If that's still in your ballpart, i'd stick to Unity's terrain.

    Here's a few links where i ran into a similar problem:
    -https://forum.unity.com/threads/multithreading-mesh-bake-physx-collisiondata.728561/#post-4871402
    -https://forum.unity.com/threads/nativearray-float-for-setheights.732437/#post-4886018

    Here's a workaround by @isaac-ashdown for using NativeArrays. The workaround will still incur a heavy penalty, not because of the processing speed, but because once you call the SyncHeightmap() method, the CPU will stall to wait on the GPU, which can be from 0.5-15ms. Some of the lag correlates to the amount of data being retrieved or how much work the GPU has, though a lot of times, it's just random. An Async SyncHeightmap() option to gather the heightmap would be able to fix a lot of the performance issues relating to runtime heightmap deformation, but it hasn't come yet.
    -https://forum.unity.com/threads/und...rendertexturetoheightmap.706679/#post-4733171

    Here's a partitioned version of the terrain in action. Dark red areas are the partitioned terrains. Blue checkered area is a single terrain manipulated via TerrainData.CopyActiveRenderTextureToHeightmap():
    -
     
    Last edited: Sep 21, 2019
  3. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Runtime updates for us are infrequent and small areas. Also Custom collision is not really the way to go now with Unity.Physics out. All of the collider creation in that is burstable now. We actually use the new Unity.Physics terrain collider with our own partitioning in addition to the Physx one. We just have some advanced Physx based controllers that we might never port, at least not right away, so the Physx terrain collider we still need.