Revision History: 5/12/06 Initial Draft
This document is written with reference to an annotated sample package, which you can find here:
This note is still in progress - illustations coming soon!
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:
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 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.
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 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.
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: 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.
Warning: because this DSF has way too few triangles for X-Plane, it will look very bad in the sim. View it in WorldMaker for best results.
The first basic mesh example illustrates a few different uses of terrain layers:
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.
One interesting thing to consider is: what shape must our mesh be? Besides placing triangles to form topography, there are other requirements.
In considering whether to project textures or use explicit coordinates, there are trade-offs.
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").
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:
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.
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 interpretted 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 proerly; 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 problme 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.
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:
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 discareded. But for a non-overlay case, you can use the NO_ALPHA flag to show the terrain without holes in it.
Typically in a DSF, when transitioning terrain there will be three regions:
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.
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:
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 geometrci 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 the nback to white. The result is a stripe of the green texture in the middle of the transition.