🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Terrain Lod and cracks

Started by
10 comments, last by StephenYates 1 year, 6 months ago

When tessellation is enabled, my terrain system uses quad patches. When a patch is further away, a lower-resolution version of the patch is used. Tessellation does a nice job of making the patch vertices match almost perfectly. In the tessellation shader I do a heightmap lookup after subdivision to adjust the height. The only problem is some small cracks can still appear:

What is a good and simple way to eliminate this problem?

10x Faster Performance for VR: www.ultraengine.com

Advertisement

Have a read of:

https://developer.download.nvidia.com/assets/gamedev/files/sdk/11/TerrainTessellation_WhitePaper.pdf

They explain how to avoid this issue. From what I remember implementing it myself, you have the edges of the higher-resolution LODs mimic the line that the lower-resolution ones adjacently produce, so that they fit perfectly.

Juliean said:
you have the edges of the higher-resolution LODs mimic the line that the lower-resolution ones adjacently produce, so that they fit perfectly.

Yeah, and with tessellation shaders, this is easy because the support tessellation factor per edge afaik?

Besides you also need seamless UVs too, but with hightmaps that's given anyway.

JoeJ said:
Yeah, and with tessellation shaders, this is easy because the support tessellation factor per edge afaik?

I think, but even in world where it didn't, the solution would still work. You just pretend that the higher-resolution edge is of lower resolution, and LERP between the edge-points there instead of fetching the “correct” value… if that explanation makes any sense?

Though in practice, the solution is a bit more complicated; the paper does a better job than I trying to explain it in detail ? Thats just he basic idea of it.

Ah yes. Flexible tessellation does not solve the cracks across different LODs ofc. Somehow i've ignored this.

But now i wonder if we could use Nanites method here too. It avoids the stitching problem by locking cluster boundaries. To unlock them, they become internal edges at the parent level of the hierarchy.

There should be a trivial way to do this for regular grid heightmaps without a need for precalculation. But right now my head is too full to think about it.

Or maybe that's overkill, and all we need is preparing a small set of mesh patches where 1-2 boundary edges do a lod down. Then we could assemble any heightmap with clipmap lod from instances of those patches.
But guess that's an old idea. Did not check the paper either. : )

The easiest way to avoid seams is just to add some overlap between the terrain tiles. I use this in my planet renderer and this method is also used in the game No Man's Sky, so it does work without complicated mesh stitching at the borders.

To make this work without artifacts (z fighting) you need to ensure that the vertices, normals, and materials/shading are exactly the same for the overlapped part. I only have overlap on 2 sides of a tile, so that they overlap kind of like roof tiles, to keep overlap to a minimum. This even works with LOD, believe it or not. There are very rare artifacts, but they mostly disappear when the terrain is textured.

Here is an example showing wireframe:

With colors showing the LOD you can see the z-fighting at overlap:

With same color and appearance with textures the seams go away completely:

Aressera said:
The easiest way to avoid seams is just to add some overlap between the terrain tiles. I use this in my planet renderer and this method is also used in the game No Man's Sky, so it does work without complicated mesh stitching at the borders. To make this work without artifacts (z fighting) you need to ensure that the vertices, normals, and materials/shading are exactly the same for the overlapped part. I only have overlap on 2 sides of a tile, so that they overlap kind of like roof tiles, to keep overlap to a minimum. This even works with LOD, believe it or not. There are very rare artifacts, but they mostly disappear when the terrain is textured.

Wow, neither heard nor thought about this. Very good to know, thanks!

Another, similar such method is using 'skirts'. So a row of quads pointing inwards under the surface. At a lod mismatch, you may see a small skirt section from either parts, but the surface appears closed, so no holes. The skirt has the same normals and texture coords than the edges it comes from, so some texture stretching can be noticable.

Now, skirts could fail if looking at the terrain from a top down view with a zig-zag mismatch, and overlaps could cause artifacts if we look along the surface plane.
But actually we could combine both those ideas to resolve both those failure cases. : )

Now that is a simple and practical solution.

10x Faster Performance for VR: www.ultraengine.com

I've implemented proper stitching (tried to integrate it with virtual texturing for displacement maps … but it comes with its own set of problems - not related to terrain or stitching):

There are no seams in geometry, as it does properly stitch each tile together - I use binary triangle trees.

I hold single vertex buffer (for all tiles), and multiple index buffers (that's where it becomes tricky). For each adjacent tile I intentionally only allow to have either same tessellation, or 1 level up or down (to perfectly stitch) - this is my additional requirement, to keep number of index buffers the same. Due to the nature of binary triangle trees - I only require 1 index buffer for even tessellation levels, and “only” 15 different for odd tessellation levels.

It still has some limitations, but is quite useful for most scenarios - I've used it in multiple production applications, and performance was never an issue (mostly mixed with just some frustum/occlusion culling approach).

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

Fundamentally it's the T-junction problem. Anywhere you have a T-junction one side will have a straight edge while the other side has two edges. That introduces gaps, holes, non-linearities, non-smooth shading and lighting, and other rendering issues.

The ideal solution is to not make T-junctions. It completely avoids the problem.

It is usually possible to adjust your tessellation system to not produce T-junctions in the first place. Choose edges that don't create a T-junction.

If you are subdividing and keeping a regular grid mesh, always keep adjacent levels between one LOD and split them internally to the quad, ensuring the outside edge remains a straight line with it's neighbor. A difficulty with this system is neighbors cannot differ by more than one level, otherwise gaps must follow.

If you're using a tessellator that moves points or creates a TIN (Triangular Irregular Network), ensure it moves a large enough distance to avoid a degenerate triangle, then introduce a triangle that fills the gap.

The other solutions mentioned, adding skirts or under-layers or slight overlaps, you can still use them for other purposes. They're not particularly expensive and can be good to hide a number of other modeling sins/errors as well.

This topic is closed to new replies.

Advertisement