Search Unity

Terrain leaking on top of a road when zooming out

Discussion in 'World Building' started by Andefob, Jul 14, 2022.

  1. Andefob

    Andefob

    Joined:
    Sep 17, 2018
    Posts:
    99
    I am using Unity 2021.3 and have an ugly terrain rendering issue (built-in rendering pipeline, forward rendering). It happens especially when road is carved inside terrain. In the image below, the road is 0.25 m over terrain everywhere but still, if camera is zoomed out, terrain will leak on top of the road. Changing the near and far clip plane of the camera don't help at all.
    terrain-leak.jpg

    Video: https://drive.google.com/file/d/1GsmA51AeCJ2N47dkxHeRjOFY5vRfFtet/view?usp=sharing

    Things that do help but have other problems:
    • Increasing resolution of the terrain makes it happen less often but does not completely solve it, and I don't want to increase resolution for performance reasons either
    • Raising the road helps a bit but even if the height is something absurd like 1 meter, it still doesn't fix the issue completely (if road is carved inside terrain)
    • If the road level is higher up (and not carved inside terrain) or the carving is smoother, the issue becomes less visible, but that is very limiting for a game with a level editor where players can make any kind of levels
    • I tried making a custom shader for the road, using Offset value. Using extreme values like -4 fix the issue in most cases, but values like -2 are not enough and already look bad when a vehicle is driving on the road since it looks like the wheels are sinking inside the road
    So, any good ideas for solutions?
     
  2. Andefob

    Andefob

    Joined:
    Sep 17, 2018
    Posts:
    99
    Answering to myself: it is because of terrain LODding - reducing Pixel Error helps but also reduces performance since triangle counts increase.
     
    JoeStrout likes this.
  3. ElevenGame

    ElevenGame

    Joined:
    Jun 13, 2016
    Posts:
    146
    Yep, that sounds correct. :D How did you fix it though? I mean having a lower LOD of the road that is slightly higher or moving the object up a bit at a distance are the only solutions I can think of right now..
     
  4. Andefob

    Andefob

    Joined:
    Sep 17, 2018
    Posts:
    99
    Still haven't found a good solution yet. reducing pixel error does help but increases the amount of triangles a lot. Syncing Road LOD with terrain LOD would be very hard since I don't think object and terrain LODding are linked in any way.

    Calling OverrideMaximumHeightError for terrain and setting the error different for those terrain patches that have a carved road might be a good solution but I haven't found any documentation about how that is supposed to work.
     
  5. ElevenGame

    ElevenGame

    Joined:
    Jun 13, 2016
    Posts:
    146
    Yeah, i wouldn't mess with the pixel error too much, it just leads to way too many polys.

    I know that terrain and object LOD are not linked directly, but they are both functions of the linear distance from the camera. Therefore if you expect a certain height error in the terrain at a specific distance and you use an object LOD there thats moved up or higher by the same amount than the error, you should be fine.. plus you might be able to save some triangles by also using a lower resolution road in the distance..
     
  6. ElevenGame

    ElevenGame

    Joined:
    Jun 13, 2016
    Posts:
    146
    The most used solution, i am quite sure, is just making the road mesh higher in general..
     
  7. Andefob

    Andefob

    Joined:
    Sep 17, 2018
    Posts:
    99
    It doesn't help enough in the case in the video - it is already lifted 0.25 m but that is already bad for gameplay. But even 0.5 or 1.0 is not enough to get rid of the graphical issues since LODding changes the geometry so much.
     
  8. Andefob

    Andefob

    Joined:
    Sep 17, 2018
    Posts:
    99
    And about raiding just the mesh, not the physics - you can pretty quickly see how the cars sink inside the meshes if it is raised and the view angle is partially from the side. It was already visible when using the Offset in shader.
     
  9. Acissathar

    Acissathar

    Joined:
    Jun 24, 2011
    Posts:
    677
    Another solution would probably be to export the terrain as a mesh if you're not relying on terrain features at runtime
     
  10. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Simply bake the road graphics into the terrain basemap. this means even if it intersects, you won't be able to tell. At this point you should fade out the actual road.

    Sadly it's not a built in feature of the Unity terrain because they don't prioritise terrain tools. So you would want to write a script that can copy a top down snapshot of roads onto the basemap that Unity generates, or your own complete replacement, perhaps from a top-down ortho editor camera and tool.

    The basemap is an all in one far lod texture of the entire terrain generated by Unity and utilising that well is key to removing issues like this.
     
    wyattt_ and ElevenGame like this.
  11. Andefob

    Andefob

    Joined:
    Sep 17, 2018
    Posts:
    99
    I don't think it fixes this issue since the error is happening much earlier than when Unity switches to using basemap. The terrain resolution is also quite low compared to to the detail level of the road.

    OverrideMaximumHeightError would still seem like the best solution - setting different values for areas where there is a road like that. Unfortunately, there doesn't seem to be any documentation about that function anywhere so I have no idea what kind of values should be used. This forum thread is the only one that has any related information: https://forum.unity.com/threads/documentation-for-terraindata-getpatchminmaxheights.1199134/

    I can already see that just adding a big bump on the terrain near the road removes the issue, even if the bump does not intersect with the road. The reason is that the area near the bump is marked to have a bigger error and lodding is thus different. So, I would have to reverse-engineer how to change the values for those areas with OverrideMaximumHeightError to affect lodding only for certain areas and not globally.
     
  12. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    You will have to move basemap forward and have a fiddle with it all. The technique I listed (fading to basemap) is used in several AAA open world titles and clearly documented on GDC such as Ghost Recon and Far Cry 5 etc, so it's kind of the done thing.

    It gets easier, of course when you roll your own terrain engine and can adjust all these parameters. Untiy's terrain limits you to pixel error and initial resolution. If your initial terrain res is too low or it's scaled too big then the popping will be big regardless of pixel error.

    So you may need a smaller scaled terrain and/or a higher resolution heightmap to also alleviate the problem along with pixel error.

    For something that changes topology a lot, you really do need to bake into basemap. Doing things like z-offset in vertex shader will also cause other problems down the line like floating or shadow bugs.

    In the end you're trying to do a lot with a limited resource so it's time to get inventive.
     
  13. Andefob

    Andefob

    Joined:
    Sep 17, 2018
    Posts:
    99
    Yes I can see how that could help but it would require lots of tuning and with the current settings as the basemap is not taken into use until much further away currently. The changes required for the fix would be much more than just being able to use OverrideMaximumHeightError for the areas where there are carved roads around. In general, this issue is such that I can have workarounds to not make it happen on my own levels but since the game has a level editor, I need a way to make it hard for players to create levels that have buggy roads.

    I wish the source code of GetMaximumHeightError (or the code that generates the values those buffers) would be public. But what I may be able to do already is just tune the values so that wherever there are carved roads, the error value has some minimum value (higher than what the current hidden algorithm produces) for the patches around it for last LOD levels.