Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


Terrain stitching micro seams


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
11 replies to this topic

#1 DwarvesH   Members   -  Reputation: 482

Like
0Likes
Like

Posted 08 April 2014 - 01:16 AM

I am experiencing a weird phenomenon. 

 

I have implemented large scale terrain that is divided into chunks of various resolutions/LOD. When two different LOD chunks are near each other, I do stitching once on the CPU to fix the seam. The way I do it is it take two points from the higher resolution chunk that align up to the lower one and compute their average height. Then I set the middle vertex height to that average and apparently this fixes all discontinuities between chunks.

 

But something is amiss. It seams hat my simple average is not up on par with the way the hardware rasterizer triangles and sometimes a single pixel wide hole appears. These come and go as you move the camera around, often staying only for one frame.

 

http://dl.dropboxusercontent.com/u/45638513/ter08.png

 

In the above image I was lucky enough to capture two of the fleeting seams near each other. The red line is the LOD discontinuity. The two seams are circled in red. As I move around the camera, white pixel come and go, all found on the discontinuity line. Otherwise, when the pixels don't show up, there are no seams.

 

Any idea how to fix this? My far plane is pretty far away, may have something to do with it.

 

The only idea I have is to add extra triangles in that "seam".

 

Thank you!

 

 



Sponsor:

#2 Hodgman   Moderators   -  Reputation: 34985

Like
0Likes
Like

Posted 08 April 2014 - 01:59 AM

The infamous "T junction" problem:

A-C-B
|/ \|
D---E

You've got lines from A-B (through C) A-D, B-D, D-E, D-C and C-E.
The line from A-B is exactly equivalent to A-C and C-B, so everything should be fine...
 
...but it's not fine! Numerical precision is such that it will never line up exactly perfectly.
The solution is to... never use T-junctions. Just say no.
 
Either you delete the A-B edge, replacing it with true A-C and C-B edges.
Or, you delete C altogether, and just have A-B, A-D, D-B, B-E and D-E:

A---B
| / |
D---E


#3 DwarvesH   Members   -  Reputation: 482

Like
0Likes
Like

Posted 08 April 2014 - 02:38 AM

ASCII diagrams. Good! Might make things clearer.

 

So I have the low LOD box XYZW and the high LOD box ACGI. Z = A and C = W. The two boxes are in separate vertex buffers:

  X---Y
  |  /|
  | / |
  |/  |
Z-A-B-C-W
  |/|/|
  D-E-F
  |/|/|
  G-H-I

The seam is at the ZW - ABC common edge, so I tried to fix it making B = (Z.Y + W.Y) / 2. So you are saying that numeric precision is not good enough for this not to give the micro seams?



#4 Hodgman   Moderators   -  Reputation: 34985

Like
0Likes
Like

Posted 08 April 2014 - 03:38 AM

So you are saying that numeric precision is not good enough for this not to give the micro seams?

Yes. In some cases (like where the height of the edge is constant) it will work, but in the general case, B will never be perfectly aligned with the LOD edge. It will be ever-so-slightly above or below the LOD edge. All joins between meshes need to happen at vertices - you can't (reliably) join two meshes by aligning a vertex with a face/edge, only by making it exactly aligned with another vertex.
 
Another fix is to move B sideways so that it overlaps with either A/Z or with C/W -- this is the same as eliminating B. Say you move B to overlap with C. The triangle formed by C-C-E ends up having zero area and disappearing (in GPU jargon, it's a "degenerate triangle"), but the A-B-D and B-E-D triangles will fill the gap.



#5 DwarvesH   Members   -  Reputation: 482

Like
0Likes
Like

Posted 08 April 2014 - 04:03 AM

 

So you are saying that numeric precision is not good enough for this not to give the micro seams?

Yes. In some cases (like where the height of the edge is constant) it will work, but in the general case, B will never be perfectly aligned with the LOD edge. It will be ever-so-slightly above or below the LOD edge. All joins between meshes need to happen at vertices - you can't (reliably) join two meshes by aligning a vertex with a face/edge, only by making it exactly aligned with another vertex.
 
Another fix is to move B sideways so that it overlaps with either A/Z or with C/W -- this is the same as eliminating B. Say you move B to overlap with C. The triangle formed by C-C-E ends up having zero area and disappearing (in GPU jargon, it's a "degenerate triangle"), but the A-B-D and B-E-D triangles will fill the gap.

 

 

Thank you for the info!

 

I would like to avoid updating vertex buffers if possible. This is what I've done in the past and it is very hard to keep the system working in real time with fast movement speed.

 

I am going to try and add a new triangle A - C - B. Actually, I'll try and pad the entire chunk with such triangles and see how that works.

 

Then at runtime one can only select an a different index buffer to enable stitching. Might give some artifacts. I need tot test it out.



#6 Norman Barrows   Crossbones+   -  Reputation: 2512

Like
0Likes
Like

Posted 08 April 2014 - 09:53 AM

i use a similar approach to create a 2500x2500 mile ground mesh ( ~ 4000km x 4000km ) at a scale of 1 foot = 1 d3d unit (~3d3d units per meter). but i'm not dealing with meshes whose vertices are non-coincident.

 

in such cases, an alternate approach to "zipping up the seams"  as i call it, is to keep them separate meshes that overlap slightly, and let the zbuffer take care of the rest.

 

but this can lead to z-fighting when far from the camera. a way to combat this is with a two pass method that renders distant stuff first with a far setting for the near and far planes, then close stuff with shorter settings for the near and far planes. the overhead of changing the projection matrix a couple times per frame is negligible.  i use a 3 pass method in Caveman, one far, one near, and a very close one for first person player weapon animations.

 

overlap means no seam fixup overhead too. i do my seam fixup when i generate static terrain chunk meshes on the fly as needed from the world map data structure. so overhead is not too bad. using dynamic meshes it would probably be much worse. i used to use dynamic meshes for the ground, but found that generating and using static chunks was MUCH faster. 


Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

 

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

 

 


#7 kauna   Crossbones+   -  Reputation: 2888

Like
0Likes
Like

Posted 08 April 2014 - 09:59 AM

You can use a pregenerated set of index buffers in order to fix the t-junction problem, no need to touch the vertex data.

 

Otherwise, the easiest solution of all is to use tesselation hardware. Just give correct tesselation factors for each edges and the problem is solved. No need for index buffers (or even vertex buffers :D). 

 

Cheers!



#8 DwarvesH   Members   -  Reputation: 482

Like
0Likes
Like

Posted 08 April 2014 - 01:31 PM

You can use a pregenerated set of index buffers in order to fix the t-junction problem, no need to touch the vertex data.

 

Otherwise, the easiest solution of all is to use tesselation hardware. Just give correct tesselation factors for each edges and the problem is solved. No need for index buffers (or even vertex buffers biggrin.png). 

 

Cheers!

 

This is what I'm trying right now. Using the same vertex buffers I have multiple sets of index buffers with extra triangles at the LOD switch edge. This approach can and will generate ugly "extruded wings" terrain artifacts, but this is only visible in debug builds where I test small LOD ranges. In practice where the change occurs hundreds of meters away from the character I can't spot the wings yet. The first time I can spot one, I might reconsider this approach.

 

I'm on DirectX 9 so tessellation is out of the question. Since I'm so inexperienced in more advanced techniques, I even shied away from from keeping my terrain data in textured and having the vertex shader sample the textures, so I'm building and updating classical vertex buffers on the fly using a far too complicated poll system.

 

Anyway tessellation scares me smile.png. But I'd love one day to graduate by implementing something like this: http://www.vertexasylum.com/downloads/cdlod/cdlod_latest.pdf

 

 

i use a similar approach to create a 2500x2500 mile ground mesh ( ~ 4000km x 4000km ) at a scale of 1 foot = 1 d3d unit (~3d3d units per meter). but i'm not dealing with meshes whose vertices are non-coincident.

 

 

Wow, that seems big. I'm having problems mapping how many height data points you have there because of the units you are using.

 

I have a ~8 km * 8 km (64 square kilometer) map, with ~8000x8000 height data points. I am having troubles with so much data, but soon I will be able to update to 100 square kilometers. Then I'm planning a 256 one and that is going to be hard. Still several orders of magnitudes smaller than your map.

 

One problem that I'm facing with size is perception. The 64 square kilometers one looks like a puny patch of ground, not a big place of adventuring. 

 

I am going to push the size up technically as big as possible, but there will come a point where I'll have to use some tricks to achieve the illusion of size. The first step is getting away from the 64 super small seeming map.



#9 PhillipHamlyn   Members   -  Reputation: 454

Like
0Likes
Like

Posted 10 April 2014 - 01:21 PM

I use a different method, illustrated here, to achieve almost infinite landscape, but it might not be to your tastes.

 

http://philliphamlyn.wordpress.com

 

An alternative I've seen used elsewhere is to drop a vertical "skirt" from all your tile edges, this is a bit of a cheat, but the user will never see the discontinuity.

 

Phillip



#10 DwarvesH   Members   -  Reputation: 482

Like
0Likes
Like

Posted 14 April 2014 - 02:28 AM

Damn you T junctions! I think I managed to eliminate all holes and solved the problem for water tight terrain:

 

 

This is my first version with "infinite" view distance. It is not needed for such small terrains, but I'm rendering distant low res terrain first with 500/20000 near/far camera and then I clear the depth buffer and render the high res terrain LODs based on camera distance, closest first, with a 0.02/6000 near far camera.

 

The terrain still feels pretty small, but I am moving with 50 m/s in that video. With normal sprint speed it does take you 8 minutes to traverse one side of the terrain.

 

And something got lost in translation, because my old XNA version had slightly better looking terrain. This one is very gray and muddy.

 

Now I just need to populate that terrain with AAA maximum quality levels found in the year 2008!



#11 mark ds   Members   -  Reputation: 1607

Like
0Likes
Like

Posted 14 April 2014 - 10:28 AM

It's looking good!

 

One thing I noticed from that video though, is that the frame rate gets lower over time (and physics takes longer), as you move towards the centre of the map. Is your culling working as expected?



#12 DwarvesH   Members   -  Reputation: 482

Like
0Likes
Like

Posted 14 April 2014 - 01:08 PM

It's looking good!

 

One thing I noticed from that video though, is that the frame rate gets lower over time (and physics takes longer), as you move towards the centre of the map. Is your culling working as expected?

 

Well the corner is the best case scenario and the center the worst case scenario.

 

The high res terrain chunks clearly affect the framerate and in the corner you have the minimum amount of high res chunks. The distant terrain is very low res. As you move towards the center, more and more terrain is rendered by high res and less by low res.

 

But I'm getting over 200 FPS without capture. And 30-40 on Intel HD :).

 

As for physics, the second number is important: that is the total from a second spent on physics. Physics has an overhead and the total time depends on how long the frame is, so it will change together with FPS.

 

And I don't agree: it is looking quite bad in my eyes. At least the view distance has come a long way since one of the first versions: 






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS