Unwanted early culling of tessellated terrain

I am continuing an older project that I started using Unity 2019.1.10f1 where HDRP was still experimental I believe. I could use the Layered Lit Tessellation shader on terrain in that version. In newer versions this doesn’t seem to work anymore.

Although I get the warning “Can’t use materials with shaders which need tangent geometry on terrain…” and is probably a heavy performance killer, it works nicely for the most part and despite partly unrealistic collision detection and grounding it achieves the graphical look that I want - getting additional detail on the terrain through layer heightmaps and elevation on top of the coarser terrain heightmap.

However I get some unwanted early frustum culling at the edges of the screen as you can see here:

I guess this is due to the fact that underlying terrain triangles would be outside the camera’s culling frustum if there was no tessellation that gave the triangle more “height”. I experimented with Camera.cullingMatrix, essentially trying to simply move the culling frustum some distance behind the actual viewing frustum. This did not work. Although I am sure that the culling frustum successfully moved, it was only possible to move it forward along the viewing direction, essentially having culled more and more on each side of the screen. Such missing triangles like in the screenshot remain however when moving it backward along the viewing direction (behind the camera).

I also tried messing around with the parametrization, amplitude, base and offset for the terrain layer tessellation. Although it reduces the problem with early culling it increases the problem with unrealistic collision detection and grounding where objects appear to float.

Does anybody know a solution to this problem? Why does the approach with the custom culling matrix does not work?

i guess the cpu is already culling the plane used to render the terrain?
then all i can think of: use 2 different heightmaps/terrain:

  • the one that is rendered uses a heightmap whose height you have raises by e.g. 10 meters in photoshop. then in the shader you push down the vertices by 10 meters first before you add tess and displacement.
  • unfortunately physixs rely on th eheightmap as well. so when it comes to the terrain collider you have to use the original height map. unity lets you assign a different terraindata her.

I’m also having the same issue with snow tessellation on terrain, the camera culling is off. I’m using this asset store snow shader: Brute Force - Snow & Ice Shader

I also tried offsetting the terrain collider, but like @sebastianzander mentioned, it causes more problems than it fixes.

I’ve also tried other snow tessellation shaders that do not have this problem, like: Minions Art’s Interactive Snow w/ Tessellation for URP

So maybe its something in the shader that sets each vertex for culling at the original position and not the tessellated position?

Seems like this is a common problem with tessellation, so I’m surprised its been difficult to find a solution online.

these quads are pretty small. so it should not be chunks being culled on the cpu side but quads being culled within the shader.
unity’s tess functions offer one that does frustum culling and degenrates (tessfactor = 0) triangles it they “are outside the frustum”. the function needs a max displacement value to work properly. maybe this is not set. and your displacement is simply way too high?

You can multiply the terrain patch bounds to fix this issue using Terrain.patchBoundsMultiplier method.

1 Like