Z-buffer Issues in the VTP Software


With roads, the problem is that the road geometry is draped simply on the ground, and will sometimes intersect it, causing Z-buffer fighting artifacts. There are a few ways to alleviate this.

  1. Lift the roads. You can set this in Enviro at startup time, with "Ground offset" in the Parameters dialog. Actually works well if your viewpoint will remain a good height off the ground, as in a flight sim. If you're extending the code, you could even make the road height vary with camera height - say 4m offset when high-elevation, 20cm when walking.
  2. Increase LOD.  Some of the conflicts occur when the CLOD simplifies the ground under the road. This can be reduced by turning up the detail on the CLOD (+/- in Enviro)
  3. Ground flattening. Some of the problem is due to level roads being draped on elevation with steep slope. With perfect, high-res elevation this wouldn't be a problem, but in practice it's a common problem. A solution would be to add a pre-processing step that 'carves' the terrain to flatten it under the roads (and buildings) - a preliminary implementation of this is in VTBuilder of roads (but not yet for buildings). This would assume enough RAM (or a small enough terrain area) to have a sufficiently high grid density to allow carving.
  4. Improved draping. Currently the roads are draped as individual segments, the heightfield is tested only at each data point in the road path. For long straight sections of road, there is the chance of road-ground intersection if the terrain is not flat in that area. This could be avoided by testing the ground along each segment and intelligently subdividing the road as needed.
  5. Polygon Offset.  OpenGL contains a feature known as "polygon offset" which can help in the case where the road is extremely close or coincident with the ground.  As Amit Patel describes it:
    "The polygon offset works at the precision of your depth buffer, so it shouldn't cause any trouble unless your objects are so close together that their distance can't be represented in the depth buffer (which would cause problems even if you don't use polygon offset).
    It's the same as manually offsetting your polygons by a tiny amount, except that (a) the offset is performed only in the camera z direction (so even if your camera is close to the ground, you won't see this offset as a visual artifact), and (b) the tiny amount can be defined in terms of the precision allowed by the depth buffer, so you really can define it to be


With water, there are complicated issues as well. Even considering just large bodies of water, shorelines are difficult with any CLOD approach. In the VTP software, it is not so bad if you have a simple texture terrain with ocean areas being flat, height=0. However, if you turn on the separate ocean plane, in order to have a high-res texture on the water surface, you will have Z-fighting between the water and the land, NO MATTER how high your Z-buffer precision is, because the two planes are intersecting each other at a steep angle. Furthermore, it becomes very visually sensitive to CLOD, since tiny fluctuation in the terrain can cause large displacement of the shoreline.

In vtlib/Enviro, i attempt to minimize this (when an ocean plane is enabled) by setting all areas with height=0 to an artificial "ocean depth", which causes an "undersea cliff", boosting the importance of shoreline vertices so that they are not culled early, maintaining the shoreline visually.

However, you still have the issue when, from very far away, the depth of the ocean is insufficient for some machine's Z-buffer precision, and it will fight with the ocean surface plane.