Question

So I have been writing a program that uses a tessellation shader and a height map to draw an environment. It starts out as a 32x32 plane, and when it gets more tessellated the heights of each square vertex are determined by the height map.

I want it so that the closer the patch is to the camera, the more tessellated it gets. However, I have discovered that this causes gaps between patches. If a patch is more tessellated than one next to it, the different resolutions cause gaps.

Here, a picture is worth a thousand words: Tessellated Environment Tessellated Environment

If two patches have the same resolution then there are no gaps. How can I get around this problem? I'm completely stuck.

Was it helpful?

Solution

The UV coordinates along the edges need to vary uniformly for this to be seamless. When done at the same level of subdivision there are some pretty reliable invariance guarantees. However, this rarely happens when the two edges are sub-divided at different rates.

Technically what you have is known as a T-Junction. It occurs because two surfaces that are supposed to share an edge actually diverge slightly. The insertion of a new displaced vertex creates two primitives, neither of which share an edge with the one primitive belonging to the adjacent patch.

You need to make the outer tessellation level identical for patches that share edges*:

   http://http.developer.nvidia.com/GPUGems2/elementLinks/07_tessellation_08.jpg

   *As shown in this diagram from GPU Gems 2

OTHER TIPS

I am sure you are already familiar with Continuous Level Of Detail problem. Searching for this in the web gives several methods solving the gap problem. One such site is here, where I copied the picture below.

One thing interesting in your case is that the tesselation does not seem to increment / decrement in 2^n fashion. So, for your case, maybe adding faces to the four boundaries of each block of terrain mesh, acting as curtains, might be the only feasible solution.

If you look at the picture below, you'll see the boundaries have vertical faces. Side effect is, if the gap is big enough, then it might be seen as a cliff. You'll need to adjust the tessellation between detail levels to minimize this side effect.

enter image description here

Here is what I ended up doing;

So I realized that only the outer tessellation levels between two patches have to match, the inner tessellation levels can be whatever they want. TCS in GLSL have you fill out the following to determine how much tessellation is done:

gl_TessLevelInner[0]
gl_TessLevelInner[1]
gl_TessLevelOuter[0]
gl_TessLevelOuter[1]
gl_TessLevelOuter[2]
gl_TessLevelOuter[3]

The four TessLevelOuter represent the tessellation levels of the four sides of the patch (the square). You are passed along the locations of each corner of the square. In order to determine the inner tessellation levels I average these four locations together and get the distance of the result from the camera. Now for each edges, which is controlled by the outer tessellation levels, I average the two appropriate corner locations and get the distance of that from the camera. Since that will have to match the patch next to it, since they share corners, this works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top