Understanding and Building DSF Meshes

Revision History: 5/12/06		Initial Draft

This document is written with reference to an annotated sample package, which you can find here:


 * DSFExamples.zip

This note is still in progress--illustrations coming soon!

Basic Meshes: Layers And Patches
A DSF mesh is built in layers. Each terrain definition from the DSF file forms a new layer. Those layers are always drawn in the order of the terrain definitions; the first definition in the file is the first layer drawn (the "bottom") of the layer stack.

If a terrain definition is listed twice in the mesh, it forms two layers; X-Plane will not consolidate layers as this would alter the draw order of the file. Therefore for fastest performance, minimize your terrain definition count when possible.

The DSF mesh is built of patches - a patch is a collection of triangles with common properties. Patches serve a few purposes:


 * Because patches share common properties, they serve as a form of file compression.
 * X-Plane will draw the mesh in patches, so they serve as a sort of spatial organization.

Patches of triangles do not have to be continuous or touching, but they should be localized to one region of the file; the entire patch will be drawn or not drawn, so if it is spread out over a large area, this will inducea lot of wasted drawing.

The Physical Mesh
The graphical mesh of your DSF can overlap, have holes, or have any number of strange artifacts; what you draw is entirely up to you.

X-Plane extracts part of the DSF mesh to form a physical mesh. Basically every triangle that is in a patch with the 'physical' flag set is copied into the physical mesh. The physical mesh must meet the following constraint:

For any given horizontal location in your DSF there must be exactly one triangle for that point in the physical mesh. In other words, the physical mesh must have no overlaps or holes!

When building up a physical mesh, X-Plane looks at all patches in multiple layers. Therefore the physical mesh does not have to come from just one layer, as long as the sum of all triangles from 'physical' patches adds up to one complete mesh when copied and merged.

Overlays
When two triangles overlap in the graphical mesh, they may cause a rendering artifact known as Z-thrash. The solution to this is to use the "overlay" flag in a patch to tell X-Plane that this triangle is going on top of an already drawn one.

When you have several triangles on top of each other:
 * The triangle from the bottom-most triangle is drawn first. Layers are always drawn in order.
 * Set the the overlay flag for every patch except for the one that will be drawn first.

Texture Coordinates And Projection
The number of "coordinates" (numbers) needed for the vertices in a DSF patch depends on the .ter file used to texture the patch and the flags on the patch. If there are too many coordinates, X-plane ignores the extras, but if there are not enough X-Plane will probably crash.

For a basic terrain mesh, the rules so far are: Projection is controlled by the .ter file - if the PROJECTED command is present, X-Plane will project the texture for you. X-Plane does not guarantee the origin of the grid the texture forms; only that it will repeat at a given distance. If you need to align the texture with the file, use your own texture coordinates. If no PROJECTED command is present, the texture will not be projected.
 * We always need a minimum of 5 coordinates: longitude, latitude, elevation, and a "delta X" and "delta Z" for the normal vector.
 * If the .ter file features a projected texture, that's all we need.
 * For the special built-in terrain called terrain_Wwater, that's all we need.
 * for a texture that is not projected, we need two more coordinates, which are used as S and T coordinates (horizontal texture position and vertical texture position) within the texture's image file. These numbers are expressed as ratios where 0.0 is the left side and 1.0 is the right side.

Textures may wrap or not, depending on whether the texture is specified with the BASE_TEX or BASE_TEX_NOWRAP routine. (The default is to not wrap.) If a texture wraps then when it reaches its edge it will repeat from the other side.

For a "landuse" terrain designed to tile, enable wrapping. When using orthophotos that must align with their neighbor, you will want to disable wrapping. The reason is this: OpenGL blends the pixels of the texture a bit to fit it over the terrain without showing pixelization. When wrapping is enabled, the left edge is blended with the right edge. But consider an image with water on the left (designed to align with a water texture on its left) and land on the right. With wrapping enabled, OpenGL will mix land from the right side with water on the left, causing the left border of the terrain to show a very thin line of land that should not be present.

One other note: while technically texture coordinates can exceed the range of 0.0 to 1.0, DSF2Text establishes limits on the range of inputs to the various parameters to the DSF file. So the DSF file format can have any texture coordinate range, but DSF2Text will only accept input files with textures of a range 0.0 to 1.0.

Alpha Channel for Base Terrain
If a terrain features an alpha channel (e.g. it is based on RGBA PNG files), then the alpha section will be transparent, revealing the terrain below. This means that you can make transparent lakes in orthophotos using the alpha channel, as long as you establish a lower layer of terrain that will be present. If an entire section of your DSF is transparent, you will probably see sky color through it or some other very strange result.

X-Plane requires more VRAM for images with alpha channels, so if you have a PNG file with an alpha channel that is entirely opaque, strip the alpha channel from the PNG file to reduce the VRAM used by 25%. Pleaes note that since PNGs are compressed, a file with an opaque alpha channel will be almost the same size on disk as one with no alpha channel. This does not reflect VRAM used; an alpha channel increases VRAM used by 33%.

You can ask X-Plane to discard the alpha channel using the NO_ALPHA command. For the purpose of the techniques we've mentioned so far this isn't a useful feature, but it's easier to understand how it works in a simple mesh. The NO_ALPHA feature will turn out to be useful in the second section when we describe borders.

Basic Mesh Example 1
Warning: because this DSF has way too few triangles for X-Plane, it will look very bad in the sim. View it in World Editor for best results.

The first basic mesh example illustrates a few different uses of terrain layers:
 * The southwest corner is built from four orthophotos (in four layers) that tile together using non-wrapped textures. This illustrates how orthophotos can be built into a mesh.  Please note that we specificy texture coordinates for these; if we asked X-Plane to project them, X-Plane would not line them up properly.
 * The northeast corner is a single wrapping terrain, projected by x-plane. This illustrates a typical "land-use" style mesh.
 * The right side shows a repeating texture that is repeated by manual texture coordinates. The north texture has water underneath and an alpha channel lets the water show through.  In the south the .ter file instructs x-plane to ignore the alpha channel.

One thing to note about this example is: the water terrain must be before the other terrain in the DSF file; this is what guarantees that the water appears under the terrain with an alpha channel.

Where Do We Need Triangles?
One interesting thing to consider is: what shape must our mesh be? Besides placing triangles to form topography, there are other requirements.
 * The border between the four orthophotos mustoccur on triangle edges. Each triangle can have only one terrain, so we can't have a triangle that spans the texture cuts!
 * Similarly, we need a triangle border on the east side between the two copies of the natural terrain. Because the texture coordinates on the east side are explicitly in the mesh, we can't have a triangle that spans the border between the two terrain files.  This is a subtle restriction but an important one.
 * By comparison, the northwest texture is projected; it will repeat on a grid no matter what the underlying terrain does.

In considering whether to project textures or use explicit coordinates, there are trade-offs.
 * With explicit texture coordinates, you must shape your mesh along the texture repeats. But your mesh will be perfectly aligned the same way every time.
 * With projected textures, your mesh can go anywhere. But the exact alignment will be decided by X-Plane.

What Flags Do We Need?
In this example, we use the overlay flags for the northwest terrain that is over water; this is because it is layered. We can set the physical flag for either the top layer (grass and fields) or bottom layer (water) but not both. Depending on our choice, this area will either act wet or dry to the airplane.

This illustrates a weakness of alpha channels to make lakes; while the shape of the lake can be anything, the physics engine does not "see" the alpha - the entire triangle is wet or dry. For this reason you may want to shape your mesh so that most of the area of lakes can be covered in triangles that consist only of water (and thus can be marked physical and act "wet").

Borders
The basic idea of borders in a DSF file is this: borders are a way to gently terminate a top layer, revealing the terrain beneath it. Without borders, we would have to either:
 * Make sure every terrain could tile with the terrain next to it (good for orthophotos but not good for generic textures), or
 * Make sure every terrain ended with alpha transparency (which would mean the edge of the terrain could only follow one contour everywhere it was used).

Bordering allows you to control where your terrain starts and ends independently of the texture of the terrain itself. It is especially well-suited for projected terrain, where you don't even know what part of the terrain will be over a certain location.

There are two types of borders: masked and dithered borders. Both use a separate texture and additional texture coordinates, but the visual algorithm is different.

One thing common to both types of borders is that the bordering techniques are only used when there is a border specified in the terrain file and the overlay flag is set! Essentially you would never want a border in a layer that wasn't on top of another one, because you must have something below the border; the border fades the layer it acts upon to transparent showing what is underneath.

Border Masking
The simpler of the two types of borders are masked borders. With a masked border, a second separate texture provides the alpha channel for a layer of terrain.

(This is the border system used for "landuse" terrain in V7 ENVs.)

To use border masking, include the BORDER_TEX (or BORDER_TEX_WRAP) command, to specify your border mask PNG file. This PNG file should be gray-scale - the single channel of gray will be interpreted as an alpha mask where black = transparent and white = opaque.

For terrain patches with the overlay flag on, you will need to provide additional texture coordinates. This means that if you have a projected texture, you will have to provide texture coordinates where there were none, for 7 coordinates total; if you have a non-projected texture you will need two sets of texture coordinates (for 9 total). The first set of texture coordinates will be applied to the terrain; the second to the mask.

The mask texture's alpha will be combined with the base texture's color to make a new masked texture that will be applied.

Bug Warning: Before X-Plane 850, 9-coordinate patches are not processed properly; the mask placement will be wrong.

Note: I do not know what the effect of having an alpha channel in the base texture would be when using masked borders. It appears from the X-Plane code that both alpha channels will be honored, but this is an unusual case; alpha masks are not usually used in repeating textures.

One important note about alpha masks: for them to work well, the terrain mesh must be shaped to allow the border masks to be positioned within whole triangles. This can be difficult if the mesh is highly irregular. This was a problem with the original X-Plane 8 US DSFs; because the mesh was highly irregular, the triangular border masks would sometimes be squeezed to be very thin, which in turn made the terrain transitions look sudden. Masked borders are better suited to a regular terrain grid.

Dithered Borders
X-Plane 820 introduced a second way to create borders: dithered bordering. Dithering borders are engaged by having a .ter file with the BORDER_TEX command and also the COMPOSITE_BORDERS command. This changes the algorithm for producing the border.

With dithered borders, we need two sources of alpha:
 * The alpha from the base terrain PNG is called the noise source and should consist of high frequency white-noise in the alpha channel. If this white noise is formed around the base image it can help the look of the terrain.  Most important is that the frequency be high--that is, that there be no large areas of a single level of alpha.
 * The alpha from the border PNG is called the ramp and is black on one side and white on the other. Essentially this ramp controls the "speed" of the border--if it contains more black, the borders are tighter and shorter, but if it contains more white, the borders persist for longer.

With a composite border, X-Plane compares the alpha color of the ramp to the alpha color of the noise source and draws that pixel of border only if the ramp is more opaque than the noise source. The result is that along the border, fewer and fewer of the pixels of the border are taken until it is gone. This is not a blend--every pixel is either entirely from the overlay terrain or not.

Because the border mask is essentially one-dimensional (horizontal) it can be curved and wrapped around any arbitrarily shaped blob of terrain. The vertical axis can be used or ignored; in the case of the global scenery, each ramp contains multiple ramps stacked vertically; the DSF uses the T coordinate of the border texture to select which curve it wants. (The curves are chosen based on the slope of the terrain.)

Another way to think about this is: the ramp controls the probability that any pixel will appear in the border - as it gets darker, less pixels are randomly picked. The noise source generates the random pixels.

One consequence of dithered borders is that the base terrain itself must have an alpha mask. This is where the NO_ALPHA command becomes useful. When used in a border, the alpha channels are used to make the decision whether to keep a pixel, then they are discarded. But for a non-overlay case, you can use the NO_ALPHA flag to show the terrain without holes in it.

Layers and Borders
Typically in a DSF, when transitioning terrain there will be three regions:
 * A base region, where only the lower-level terrain is present. Overlay flag is not set, and the physical flag is set.
 * A transitional region. The base region is present (overlay flag not set and physical flag set) and a higher layer is present with the overlay flag set and physical flag not set.
 * A top region, where only the top layer ise present, but now its overlay flag is not set and its physical flag is set. Essentially once we have reached a mix of 100% top texture, we can drop the base region and turn off overlay features and we are back to a single terrain.

There is also no limit to the number of borders on top of each other; a third terrain could start transitioning in with border patches on top of the situation described above.

Basic Mesh Example 2
The second basic mesh example shows a series of borders. The file is split; the west side shows borders using masking, and the right side shows borders using dithering.

On each side, the file is split into four sections from south to north:
 * The bottom quarter contains only water, a single base layer.
 * The second quarter contains borders on top of that water.
 * The third quarter contains the terrain from the second quarter, but now it has become the base and a new texture comes in as a border.
 * The fourth quarter contains only the border terrain from the third quarter, acting as a base.

In this way we have three layers of terrain fading out in steps.

The masks on the left side show two different uses of masks; the southern mask is a geometric shape, cutting into the water at angles. The top mask contains translucency, causing a smooth alpha blend from one texture to the next.

The dithering masks on the right side show some of the properties of the ramps. For the lower dither, the ramp is just a straight cutover, causing more and more of the checkerboarded noise pattern to show up. But on the top, the ramp goes from black to white, then back to black then back to white. The result is a stripe of the green texture in the middle of the transition.