article_type: Legacy Info

Low Frame Rate with GeForce FX Video Cards

Affected Versions of X-Plane: 8.64, 9.00 Affected Operating Systems: Mac OS X, Windows, Linux Affected Video Cards: GeForce FX series (GeForce FX5200-5950)

Description: framerate is significantly slower when pixel shaders are in use.

X-Plane 8: pixel shaders are engaged when “high detailed world” check-box is checked in the rendering settings. X-Plane 9: pixel shaders are engaged when “use pixel shaders” are checked in the rendering settings.

This is a known limitation with the GeForce FX series of video cards; their performance is significantly faster when pixel shaders are not used. This is not an issue with the newer GeForce cards (6, 7 and 8 series).

Leave a comment

Lock Failed Fatal Error

This issue affects X-Plane version 8 on Linux. This issue does not affect X-Plane version 9 on Linux.

Some distros of Linux will give this error when running any X-Plane 864-generation application or installer.

xcb_xlib.c:50: xcb_xlib_unlock: Assertion 'c->xlib.lock' failed.

The problem is that libxcb became a lot more picky about reentrancy, breaking about a billion different packages…do a google search on that assert to see the fallout! (Apparently AWT was among the offenders.)

As far as I can tell most distros that have this problem have an environment variable to turn checking off, so you can run x-plane like this:

LIBXCB_ALLOW_SLOPPY_LOCK=1 ./sim

(or whatever is appropriate for your favorite shell). If this does not fix this problem, you’ll need to find out how to get the xcb patch for your particular distro.

As far as I can tell, running with the sloppy locks environment variable does not affect sim performance in any way. X-Plane 9 does not have this problem.

Alternatively you could insert

export LIBXCB_ALLOW_SLOPPY_LOCK=true

at the end of your “/etc/profile” file. This turns the check off on every boot.

Leave a comment

Exterior Aircraft Lighting in X-Plane 9

This example plane demonstates some of the airplane exterior lighting features that are possible in X-Plane 9.

You can download the example plane here: File:Example beacons.zip

Overview

This example plane demonstates some of the airplane exterior lighting features that are possible in X-Plane 9:

  • Left and right landing lights are separately controlled.
  • Landing lights have two intensity levels (low and high).
  • Landing lights illuminate the fuselage of the airplane.
  • Logo lights illuminate the tail (billboards are visible on the wing-tips).
  • Strobe pattern is customized.
  • Front and rear wing strobes flash separately.
  • The two rotating beacons rotate at different rates.

This tutorial covers the following X-Plane material:

  • Parameterized Lights
  • Datarefs for light control
  • Use of ATTR_light_level

You Should Already Know

To understand this example plane, you should already know:

  • How to model a plane in Plane-Maker.
  • How to create a panel, including generic instruments.
  • How to build the exterior out of OBJ files from a 3-d modeler.
  • How to attach “named lights” to create lighting billboards.

You may want to review Lighting Definitions for terminology. This tutorial focuses mostly on billboards and halo effects; you can build light fixtures in a 3-d modeling program.

Landing Lights

X-Plane simulates up to 16 separately controllable landing lights (plus one taxi light). You can use named lights to map any number of billboards to any of these simulated lights.

If any of the 16 landing lights is on, X-Plane will draw a landing light halo effect on the runway in front of the airplane. (The quality of this effect will vary with hardware capability.)

The location of the landing light halo effect on the pavement is determined by the landing light location in the Plane-Maker view dialog box’s exterior lights tab. Note: Even if you do not enable the landing lights in this tab, the location of the halo will be determined by this. X-Plane draws only one halo, so if you do not enable these lights, set the first light’s location to something appropriate for the centerline of the airplane.

Data Refs

The dataref

sim/cockpit2/switches/landing_lights_switch

is an array of floating point values that you can use to turn the landing lights on and off. The landing light switch is a ratio with 0 being off, 1.0 being full intensity, 0.5 being 50% intensity, etc. Each landing light can be set to a different intensity, or be individually turned off and on.

The dataref

sim/flightmodel2/lights/landing_lights_brightness_ratio

Tells the actual effective brightness of the landing light for visual effects – it takes into account electrical system and landing light failures, as well as the delay for the bulb to warm up and cool down. It is also an array of 16 floating point values – 0.0 is off, 1.0 is full brightness.

There are two legacy datarefs:

sim/cockpit/electrical/landing_lights_on
sim/cockpit2/switches/landing_lights_on

That date back to older versions of X-Plane. Use the newer datarefs for more control – these datarefs will turn all of the landing lights on and off at once.

3-Way Panel Switches

X-Plane comes with a built-in “landing light” switch – don’t use it. It will only affect the first landing light. Instead, use generic instruments to write to the sim/cockpit2/switches/landing_lights_switch switch.

In our plane, we use a 3-position rotary. A key frame table matches the 3 positions to off, 50%, and 100% brightness.

Customizing the Landing Light Billboards

For the billboards under the wings, we do not use the built-in landing lights from the view dialog box of Plane-Maker. Instead we attach parameterized lights to our OBJ.

A parameterized light is like a named light: it is a billboard attached to your object at an XYZ location. The name defines what the billboard will look like. But unlike a named light, a parameterized light lets us customize the look of the light. Our object contains this:

LIGHT_PARAM airplane_landing_size -0.822960 -0.152400 1.737360	1.5	-3 0
LIGHT_PARAM airplane_landing_size 0.822960 -0.152400 1.737360	1.5	-3 1

The first 3 numbers are the location in meters relative to the attachment point of the fuselage object that the lights are part of. The next numbers meanings depend on the type of parameterized light. In our case (landing light by size) they are:

  • The size of the billboard (1.5). Billboard sizes don’t correspond to meters – you’ll have to experiment to find appropriate sizes.
  • The tightness of focus. Negative values are visible from the front of the plane, positive from the rear. Larger magnitude numbers make a light that is visible from a smaller angle.
  • The index number of the light. So the first billboard on the left side is tied to landing light #0, the second one is tied to landing light #1. (Array indices for datarefs count from 0.)

Thus the two landing lights are independently controllable.

Note that you can make many light billboards (with LIGHT_PARAM or LIGHT_NAMED) for a single x-plane landing light. So for example, you can model a landing light in a wing with several bulbs.

Adding Halos To The Fuselage

To create the illusion of the landing light shining on the fuselage, the _LIT texture for the fuselage object has the lighting halos for the two landing lights and tail drawn in.

We can use ATTR_light_level to control the brightness of the light texture for a certain set of triangles. What makes things difficult is that we can only have one _LIT texture. So it is important that we design our lights with no overlapping regions. (We have no way to select one of multiple halos that would intersect in the LIT texture.) In our object we have this:

ATTR_light_level 0.000000 1.000000 sim/flightmodel2/lights/landing_lights_brightness_ratio[0]
TRIS 0 882
ATTR_light_level 0.000000 1.000000 sim/flightmodel2/lights/landing_lights_brightness_ratio[1]
TRIS 882 669
ATTR_light_level 0.000000 1.000000 sim/flightmodel2/lights/generic_lights_brightness_ratio[0]
TRIS 1551 435

The mesh is divided into three parts, and each part has its lit level tied to one of the brightness ratios – two for the landing lights, one for the tail logo lights (see below).

Note that we do not use the switch datarefs, we use the filghtmodel2/lights/ datarefs to get the actual brightness. This way if our electrical system dies, the halo effect will disappear from the fuselage even if the switch is turned to the “on” positions.

Tail Logo Lights

The tail logo lights basically repeat the strategy we used for the landing lights, but with one difference: we don’t want a halo to appear on the runway because the logo lights are turned on. But we get a halo on the runway if any landing light is turned on. Clearly we can’t “recycle” one of our 14 remaining landing lights for the tail.

Fortunately, X-Plane also provides 64 “generic” lights. A generic light is a bulb simulated in X-Plane, similar to a landing light, but without producing a halo effect on the runway. We can use them for any purpose. In our case we will use a generic light to simulate logo lights projecting back from the wing tips to the tail.

Something to note: while our plane appears to have two logo lights (one on each wing tip lighting each side of the tail) we only use one generic light for both. This is because we don’t model turning the left and right logo light on separately. Thus we can just use one generic light, and use two billboards. There is no requirement to use one generic light in X-plane for each real-world bulb on the plane.

Data Refs

Like the landing lights, two datarefs control the generic lights. The switch position is also a ratio from 0.0 to 1.0:

sim/cockpit2/switches/generic_lights_switch

and the brightness (taking into account the electrical system, etc. is found in

sim/flightmodel2/lights/generic_lights_brightness_ratio

where 0.0 is off and 1.0 is full brightness.

3-Way Panel Switches

There is no pre-made instrument switch for generic lights – we must use a generic instrument (in our case another 3-way rotary) to map to sim/cockpit2/switches/generic_lights_switch.

Adding Halos To The Tail

Like the landing lights, we use ATTR_lit_level to fade the _LIT texture on the tail.

Adding Billboards To The Wing Tips

We want to put a pair of billboards on the tails so that when a user looks from the tail to the wing-tip, the bulb appears. Once again we use parameterized lights so we can customize the light’s properties a bit. But here we have a problem: the parameterized lights only face forward or backward. How do we angle the lights inward toward the tail?

The answer is animation. Directionally sensitive billboards in X-Plane are affected by animation. We can build a “static” animation (an animation whose animated position never changes) to “aim” the billboard at the tail.

ANIM_begin
ANIM_trans -4.906825 0.121920 2.7 -4.906825 0.121920 2.7 0.000000 0.000000 none
ANIM_rotate 0 1 0  250 250    0 0 none
LIGHT_PARAM airplane_generic_size 0 0 0	1.5 -3 0
ANIM_end
ANIM_begin
ANIM_trans  4.906825 0.121920 2.7 4.906825 0.121920 2.7 0.000000 0.000000 none
ANIM_rotate 0 1 0  120 120    0 0 none
LIGHT_PARAM airplane_generic_size 0 0 0	1.5 -3 0
ANIM_end

The lights are being rotated around an arbitrary point, 250 degrees for the first light, and 120 degrees for the second.

Beacons And Strobes

For our airplane, we want to accomplish a few specialized effects with the beacons and strobes:

  • We want the strobes to flash in an irregular pattern (short long, short long).
  • We want the first flash to come from the front of the wing, and the second one to come from the back of the wing.
  • We want the two red rotating beacons to flash at different rates.

X-Plane 940 models four separate strobes and four separate beacons. Normally they will all flash or rotate in sync in a preset pattern. But we can use a plugin to take over the behavior and program our own pattern. So we have a 2-part task:

  1. Program our own pattern, and
  2. Use parameterized lights to place strobes and beacons on our airplane OBJ that respond to the right strobe or beacon number.

Parameterized Lights For Beacons and Strobes

Once again, we will not use the built-in exterior lights; instead we will place our own in an OBJ. In the exterior lights tab of the view dialog box in Plane-Maker, all of the specific lights are off, and the options to have Plane-Maker place lights for us is off too.

In our fuselage object file we have:

LIGHT_PARAM airplane_beacon_size 0.000000 0.643128 0.000000 1.5 0 0
LIGHT_PARAM airplane_beacon_size 0.000000 1.594104 3.383280 1.5 0 1

This is a pair of rotating beacons; these are parameterized lights. The first parameter is size. The second parameter (0) makes the light omni-directional. And the third light is the index number of the 4 beacons. So the second beacon is on the tail, the first is on the fuselage.

(Note that unlike landing lights, all four beacons simulated in the system are controlled by one switch. The same applies for the strobes.)

Our nav lights on the wing tips are simple named ilghts

LIGHT_NAMED airplane_nav_left -4.906825 0.121920 2.197132
LIGHT_NAMED airplane_nav_right 4.906825 0.121920 2.197132

Finally, the strobe wings. We have two on each wing-tip.

LIGHT_PARAM airplane_strobe_size -4.906825 0.121920 2.097132 2 -0.25 0
LIGHT_PARAM airplane_strobe_size 4.906825 0.121920 2.097132 2 -0.25 0
LIGHT_PARAM airplane_strobe_size -4.906825 0.121920 2.397132 2 0.25 1
LIGHT_PARAM airplane_strobe_size 4.906825 0.121920 2.397132 2 0.25 1

The first parameter is size, the second directionality (again, negative means “visible from the front”, and smaller numbers are less directional), and the last number is the index of the strobe. So the front strobe is index 0, the back strobe is index 1.

Again, note that the number of strobes that the sim simulates is not the same as the number of billboards. We have two strobes, but we have two billboards for each (one on each wing). So the system simulates two strobes (for a two-stage flash) but we see four billboards.

DataRefs And Plugin

Without the plugin, the strobes would flash all four in sync, once a second, and the beacons wouild flash in unison. We use a fat plugin in the aircraft’s plugins folder to override this behavior.

The full source of the plugin and complete downloadable project files an be found on the X-Plane SDK website: //www.xsquawkbox.net/xpsdk/mediawiki/Beacons_and_Strobes.

These are the datarefs that affect strobe and beacon operation:

sim/flightmodel2/lights/override_beacons_and_strobes

When you set this dataref to 1, you take control away from X-Plane and manage the strobes and beacons yourself. You must manage both – there are not separate overrides for beacons and strobes. Be sure to set the dataref back to 0 when your plugin is unloaded!

X-Plane will set these datarefs to be 1 if the beacons and strobes have power and 0 if they do not:

sim/cockpit/electrical/beacon_lights_on
sim/cockpit/electrical/strobe_lights_on

Use these datarefs (and not the raw switch datarefs) to decide whether the strobes and beacons should light up – that way your strobes and beacons won’t work if the battery or electrical system fails.

These datarefs are updated by X-Plane once per frame, unless you override the beacons and strobes; in that case your plugin must update them.

sim/flightmodel2/lights/beacon_brightness_ratio
sim/flightmodel2/lights/strobe_brightness_ratio
sim/flightmodel2/lights/strobe_flash_now

The brightness ratios are 4-item float arrays – 0 means off, 1.0 means full brightness. The default beacons and strobes that Plane-Maker creates always show index 0, but you can use parameterized lights to show the other indices.

strobe_flash_now is an int – set it to 1 if any of the strobes is flashing; X-Plane checks this dataref and creates a “flash” effect in the cockpit when you are in the clouds or fog and the strobes are on.

Leave a comment

Z-Buffer

X-Plane uses a technique called z-buffering to draw in 3-d. Basically for every pixel drawn on the screen, X-Plane remembers how far away from the viewer it is. When a new model is drawn, only pixels that are closer to the viewer are visible.

If X-Plane did not use Z-Buffering, then objects that were behind a hill would be drawn over the hill. With Z-buffering, the hill obscures the object even though it is drawn first.

Image:about_obj8_zbuf.gif

In the picture on the left, the buildings are drawn in the order numbered. But Z-buffering assures that closer buildings appear on top. For example, building 7 is partly not drawn because building 6 is “closer” to the veiwer. On the right, Z-buffering is disabled; the effect is similar to overlaying paper cutouts.

A problem happens when you have a piece of your model overlaying the ground. Due to a lack of precision on the graphics card, in some places the model will be drawn over the ground, and in some cases the ground will be drawn over the model. This is called Z-Buffer Thrash.

Image:about_obj8_zthrash.gif

In the picture above, the two helipads are objects that touch the terrain. On the left the polgon is thrashing with the terrain; on the right a polygon offset of 1 has been applied, so it draws cleanly.

For information on avoiding Z-buffer thrash in your object models, see the OBJ Overview article

Leave a comment

Using Polygon Offset

This page is not yet finished. Information may be incomplete! If you have information on this topic, you may be able to help complete the article.

Polygon Offset is an OBJ modeling feature that allows you to stack multiple layers of polygons on top of each other without flicker. Polygon offset is set in an OBJ file via an ATTRibute (ATTR_poly_os) but is usually set using a plugin or script for your modeling program.

Legal polygon offset values are 0 (no offset) or positive integers.

The polygon offset value does not define a layer order. It does define the “strength” of anti-Z-thrashing applied; generally you should use the smallest number you can get away with to avoid other artifacts.

Draw Order and Polygon Offset

It is critical that the draw order of any geometry with polygon offset is:

  1. The base geometry.
  2. All overlay layers, in the order they should be overdrawn. All overlay layers should have the same polygon offset values!
  3. Any geometry that appears on top of the overlay (e.g. 3-d elements on top of the flat elements).

Within an Object

Within an object, X-Plane respects the draw order you pick, so be sure to order your geometry based on the above rules.

Within an Airplane

Within an airplane, the draw order is based on:

  1. Outside cockpit object
  2. Outside-lighting objects, by order in the attachment dialog box.
  3. Inside-lighting objects, by order in the attachment dialog box.
  4. Inside cockpit object
  5. Glass-lighting objects, by order in the attachment dialog box.

Within Scenery

Objects are sorted by the ATTR_layer_group directive; within a layer group, the order is determined by X-Plane.

Leave a comment

Using Photoshop to Cut Images for X-Plane Scenery

In order to use an image in X-Plane scenery–that is, in order to save it for use in the X-Plane sim rather than just for design use in World Editor–the image must have exactly one of the following resolutions (in pixels):

  • 2 x 2
  • 4 x 4
  • 8 x 8
  • 16 x 16
  • 64 x 64
  • 128 x 128
  • 256 x 256
  • 512 x 512
  • 1024 x 1024
  • 2048 x 2048

Obviously, no one wants to create 2 x 2 photo imagery. Realistically, anything under 512 x 512 is unlikely to be used in scenery.

The image must also have either a PNG, BMP (not recommended), or DDS file type.

In this tutorial, we’re going to take a rectangular GeoTIFF and cut it down into images that can be used in X-Plane scenery. The original file had a resolution of about 4,000 x 8,000. Our finished images will all be 2048 x 2048 PNGs.

To begin, open the original image in Photoshop. The screenshots here are taken from CS4, but the tools we’re using have been in Photoshop since around version 7.

Select the slice tool from the toolbar, as in the image below.

Image:1 slice tool.gif

Set the slice tool to use fixed sizes, then input an appropriate size for your image (as in the screenshot below). As our image is quite large, we’ll be cutting it into 8 images (2 across, 4 down), each of 2048 x 2048 resolution.

Image:2 use fixed sizes.gif

Draw your slices and move them as necessary. When you’re done, open the File menu and click Save for Web and Devices, as in the screenshot below.

The program may warn you about the size of your image. Don’t worry–we don’t actually intend to use our 2048 x 2048 images on the web!

Image:7 warning.gif

Zoom out so that you can see all of the slices that you intend to use.

Zooming out in the Save for Web dialog

Zooming out in the Save for Web dialog

Use the slice select tool (found on the left side of the Save for Web dialog window) to select all the slices you intend to use.

Selecting slices

Selecting slices

Select the PNG-24 preset in the upper right corner to set all of the images to be saved as PNG files.

Selecting PNG-24

Selecting PNG-24

Click the Save button, then navigate to your scenery package’s folder. For instance, in the image below, my scenery package is called “KOJC Johnson County Executive,” so I’m saving to the directory:

X-Plane\Custom Scenery\KOJC Johnson County Executive
Selecting the scenery package folder

Selecting the scenery package folder
Leave a comment

Understanding and Building DSF Base 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:

  • 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.

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 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.

3 Comments

Customizing X-Plane 8’s Default Scenery

 
	Revision History
		 5/08/05	Initial Draft

This tutorial explains how to create a custom scenery package that replaces
some of X-Plane 8’s default graphics with customized ones.

What you need to do this tutorial:

Before you begin you will need the following:

  • An installation of X-Plane 8.11.
  • A good text editor.
  • A good image editor that can edit PNG files.

Overview of the Process.

The basic steps to this process are:

  1. Clone a new version of the roads scenery package.
  2. Add night textures to the default road textures.
  3. Copy the urban texture from the default scenery to our package.

Cloning the Roads Scenery Package

To start this tutorial, we’ll make a copy of the default X-Plane roads scenery
package that we can modify.

1. Copy the folder ‘x-plane roads’ (found in the Resources/default scenery folder) into the ‘Custom Scenery’ folder, and rename it ‘new artwork’.

From this point on we will make all of our changes to this newly copied ‘new artwork’ folder. Even though ‘new artwork’ is going to contain no DSF files, it still acts like a custom scenery package; X-Plane will search it before the default roads folder when it looks for road definitions.

How does X-Plane know how to find roads in our new scenery package? Well, we copied the “library.txt” file from the default roads folder; this library.txt file tells X-Plane what useful things are in our package. We’ll use this file later to add some terrain textures.

Adding Night Textures to the Roads

The default roads do not contain lit textures, but we can add them. First we must tell X-Plane where to find our lit textures.

2. Open the text file road.net. After each TEXTURE command add a TEXTURE_LIT command.

The end results should be:

 
TEXTURE 3 highway.png
TEXTURE_LIT highway_LIT.png
TEXTURE 3 secondary.png
TEXTURE_LIT secondary_LIT.png
TEXTURE 3 local.png
TEXTURE_LIT local_LIT.png
TEXTURE 0 highway.png
TEXTURE_LIT highway_LIT.png
TEXTURE 0 secondary.png
TEXTURE_LIT secondary_LIT.png
TEXTURE 0 local.png
TEXTURE_LIT local_LIT.png

3. Create _LIT variants of the local, highway and secondary PNG files with night lighting.

How you make lighting textures is up to you; for the purpose of this tutorial I’ve made some pretty ugly ones just to save time, which you can grab here if you want:

Adding a New Customized City Texture

We can also override the default city texture from our new scenery package. We’ll need to copy the related files from the default resources folder to our custom scenery package.

4. Copy the files border.png and urban.ter from Resources/default scenery/x-plane terrain to your custom scenery package.

A “.ter” file is a terrain info file – a text file that tells X-Plane how to draw terrain. It refers to the various bitmaps needed to draw the terrain and also has settings. We’ll start by
copying the existing urban terrain file.

5. Modify the urban.ter file.
 
	A
	800
	TERRAIN
 
	BASE_TEX urban.png
	LIT_TEX urban_LIT.png
	BORDER_TEX border.png
	PROJECTED 4000 4000
	NO_ALPHA

We are modifying the terrain file to have a base texture and a lit overlay, but no “composite” layer. The NO_ALPHA directive tells X-Plane to ignore any alpha channel (should we have one), and the PROJECTED directive tells x-plane that one copy of this texture should cover a 4000×4000 meter square.

6. Create a new 1024×1024 city terrain texture called ‘urban.png’.
7. Create a new 1024×1024 city light map texture called ‘urban_LIT.png’.

Again I have created two quick urban textures just for demonstration purposes in this tutorial.

Urban.png was made by copying and cutting out an area of orthophoto from the KSBD area via TerraServer-USA. The urban_LIT.png file was created by applying Photoshop color-response curves and some blur filters to bring out certain details with a yellowish tinge.

8. Add a new line to the library.txt file in your custom scenery folder.
 
A
800
LIBRARY
 
EXPORT lib/us/roads.net road.net
EXPORT lib/terrain/urban.ter urban.ter

How is X-Pane finding all of this stuff? The answer is the library.txt file in our scenery package. This is a directory telling X-Plane what items we are providing. The first line tells us that the scenery resource “lib/us/roads.net” can be found in the file “road.net” in the root of our scenery package. The second tells us that the scenery resources “lib/terrain/urban.ter” can be found in the local file “urban.ter” in the root of our scenery package.

The first path in these “EXPORT” directives are the virtual path, a file path into an imaginary scenery package that is then translated by X-Plane into many real scenery packages by library files. How would you know the correct virtual paths? Just look in the library.txt files of the default scenery to see what we’ve named our various scenery objects and terrains. Almost
every art resource that is included in X-Plane for default scenery has a virtual path.

Viewing the results.

To use the results, just have your custom scenery package in the custom scenery folder and start X-Plane.

KSBD metro area - no objects or roads, day.

KSBD metro area – no objects or roads, day.
KSBD metro area - no objects or roads, night.

KSBD metro area – no objects or roads, night.
KSBD metro area - insane objects and roads, day.

KSBD metro area – insane objects and roads, day.
KSBD metro area - insane objects and roads, night.

KSBD metro area – insane objects and roads, night.
KSBD metro area closeup - insane objects and roads, day.

KSBD metro area closeup – insane objects and roads, day.
KSBD metro area closeup - insane objects and roads, night.

KSBD metro area closeup – insane objects and roads, night.

You can grab the entire custom scenery package from this tutorial here.

Postscript: File Name Flexibility

It is worth noting that the file names in X-Plane 8’s scenery system are for the most part not fixed! Here are some of the ways you can pick your own file names if you so desire:

  • You can name your custom scenery package anything you want.
  • Your roads.net file can have any file name with the .net extension, as long as the second file name in the library.txt file matches it. (This is the local path of the library.txt file and can be varied. The virtual path lib/us/roads.net must be kept the same.)
  • The textures for the roads.net file can be anything – simply make sure the TEXTURE command in the text .net text file matches your PNGs. (This is just like an OBJ.)
  • The lit textures for the roads do not have to have the same names as the daytime textures–again, any file name referred to by the TEXTURE_LIT command is allowed.
  • The urban.ter file can have any file name with a .ter extension as long as the second file name in the library.txt file matches it. The virtual path lib/terrain/urban.ter is fixed.
  • The bitmaps that urban.ter refers to can have any file name as long as urban.ter matches your PNGs. Lit textures can have any name referred to by the TEX_LIT command.

You also have flexibility of location. For example, if you want to put all of your road items in a subfolder called “roadstuff” and textures in a folder called “urban” you could have this in the library.txt file:

 
A
800
LIBRARY
 
EXPORT lib/us/roads.net roadstuff/road.net
EXPORT lib/terrain/urban.ter urban/urban.ter

To adjust the package, you would have to move the highway files (highway_LIT.png, secondary_LIT.png, secondary.png, road.net, pylon.png, local.png, local_LIT.png, highway.png, powerline_tower.obj, powerline_tower.png) to the new “roadstuff” subfolder and the terrain files
(urban_LIT.png, urban.png, urban.ter, border.png) to the new “urban” folder. Note that the path in library.txt points to the text file – all bitmaps and other items referred to by that text file are found using relative paths, and therefore must go with the .ter or or .net file. The file library.txt must not be moved or renamed; X-Plane looks for it by name in the root of your scenery package.

Leave a comment

Flat Shading and Normal Maps

This page is not yet finished. Information may be incomplete! If you have information on this topic, you may be able to help complete the article.

> Quick question about normal maps – what happens to ‘traditional’
> smooth/flat shading attributes when a normal map is present? For
> example, the kind of vertex normal instructions set by the ‘edge split
> angle’ control in AC3D? Are they ignored, or do they have some kind of
> effect still?

Well, there are 3 things going on here:

1. What happens with flat/smooth shading in ac3d.
2. What ATTR_flat does in a file.
3. What normal maps do.

And they are (fortunately for my sanity) all independent.

First: ac3d. Ac3d doesn’t generate flat shading attributes any more. 🙂 If ac3d says the surface is flat (because it is flat shaded OR below the crease angle) ac3d actually gives me (the exporter) per-vertex normals that happen to be aligned for flat shading.

In very old versions of the plugin I did generate ATTR_flat when I detected that we really were in flat shading but…it turns out it’s worth eating the vertex count (see below) to avoid attribute changes.

Second: what is flat shading? Basically flat shading can be thought of as sort of a “sustain pedal” for normals…in flat shading, the normal that “provokes” the triangle (that is, normals # 3, 6, 9, etc. the ones that are emitted last before the triangle) are the ones used to shade the entire triangle. You can think of it as “smearing” the 3rd, 6th, and 9th normal back over the previous two.

So when we export a flat shaded object, basically ac3d has done this in advance. Anything you can do with flat shading, you can do with smooth shading by pre-changing the normals.

(Note that both modes still interpolate lighting over the entire triangle! If you had per vertex spot lighting, each corner would be lit differently. The “smoothness” of a curved surface comes from having different normals in each corner of the triangle, even though in truth the triangle is, by definition, planar.)

Just from this we can see a side-effect of not having flat shading: more normals. If we had a cube where the XYZ and ST coordinates of each vertex were the same for the shared vertices of each face (in other words, no texture discontinuity) we can share the vertices with flat normals (because the normal that provokes might not be the one we have) by carefully picking which normals provoke.

With smooth shading, we have to copy the vertices just so we can have different normals for different faces (to get that “crisp” edge).

Back in v6 when we cared about every vertex, this copying was a problem. In v9, where we can have 50,000 vertices, we really don’t care anymore…we care more about the ATTR. (Also, most high vertex count meshes I’ve seen come from round things where we need smooth shading anyway. Optimizing a cube down from 24 to 8 vertices isn’t worth it.

Now there’s one more issue: in the old days, with flat shading, we could simply specify one normal per each 3 or 4 vertices. This is now a very bad idea…modern hardware sucks up vertices at high speed _only_ when every vertex has the same layout. So we can’t get a win there. (That s to say, flat shading is an API feature that might not exist if OpenGL were built today for today’s hardware from scratch.)

Third: okay. So we have normals coming in per vertex, and OpenGL is looking at all of them, or only the provoking one, and then interpolating them across the triangle to get a roughly interpolated normal per pixel. That’s what you get when you use per-pixel lighting with no normal map.

The normal map takes that interpolated normal and the texture coordinate system and builds a coordinate system (called “tangent space”, because it is a coordinate system tangent to the surface). The normal vector from the normal map is translated into that coordinate system.

So…the “basis” for the normal map will be very simple, constant and boring if you have flat shading, whether from ATTR_flat or from ac3d. If you have smooth shading and a “curved” surface, a pure blue normal map (no bumps) will still curve.

Leave a comment

Custom Lighting Billboards

This article lists the ways you can create lighting billboards in X-Plane for scenery and airplane use. They are listed in order of decreasing abstraction. Generally you should:

  • Use the highest level of abstraction that meets your needs. This gives X-Plane the best chance to optimize rendering of your light billboards.
  • Do not “abuse” an abstraction. For example, if you need blue lights for a police station, don’t use taxiway lights; taxiway lights are for airports only, and using them implies an airport surface area.

apt.dat Lights

The simplest way to create lighting is using an apt.dat airport layout; the apt.dat file format supports most common lighting fixtures found around an airport.

You can edit apt.dat lighting using WorldEditor[1]. More information on the apt.dat format can be found at //data.x-plane.com/

There are a few lighting types that are much easier to create with an apt.dat than any other file format. In particular, sequenced flashing lights like the “rabbit” in an approach lighting fixture get their sequencing information from the apt.dat loading code. If you use the “rabbit” art assets using an overlay DSF (see below) you will not be able to create the flashing sequence.

apt.dat lights have a very high level of abstraction. For example, runway lights automatically change their color based on distance to the threshold and their fixture type (flush vs. above-ground) based on the presence of taxiways.

DSF Overlays

For more control of lighting, use a DSF overlay[2] to place objects. The objects in turn can create the desired billboard.

Because all of the objects used to model airports (from apt.dat files) are also available via the X-Plane library system[3], you can gain more additional control of object placement using a DSF overlays.

For example, if you need taxiway centerline lighting with a spacing other than what the apt.dat file automatically generates, you can individually place taxiway centerline lights from the library using an overlay DSF.

You can create DSF overlays with OverlayEditor[4] (third party) or WED 1.1 (once it goes beta – alpha as of this writing).

With Library Art Assets

The simplest way to use an overlay DSF is to use lighting objects already present with the sim. The main use for this would be to customize placement of airport lighting beyond what the apt.dat file can do. See the notes above about the limitations of using “sequenced” lights.

With Custom Objects

The next level of customization is to create your own OBJ files, which lets you model the light fixture in 3-d. There are a number of ways to get billboards for your 3-d models. Custom objects are always placed into the scenery system via a DSF overlay.

You can create objects with plugins/scripts for Blender or ac3d[5].

With Named Lights

The simplest way to place a billboard into your custom object is to use a named light. Named lights provide access to X-Plane’s built-in shaders and light billboard textures. Named lights are the best choice when you need to place a lot of lights.

With Custom Lights

A custom light is a light billboard in an object where you provide all of the parameters for the light’s operation. The custom light’s texture comes from the OBJ. The custom light has nine configurable parameters and a dataref. Thus you can customize its operation in three ways:

  1. No dataref – if you do not provide any dataref, the 9 parameters are used as-is.
  2. X-Plane dataref – X-Plane comes with a number of datarefs for light animation. See sim/graphics/animation/lights/[6]
  3. Plugin-dataref – you can provide your own dataref to modify lighting parameters in a plugin[7]. This gives you complete control of the light from code.

Plugin Drawing Callback

At the lowest level, you can simply install a drawing callback using XPLMRegisterDrawingCallback, and then draw your own billboards using any OpenGL code you want.

Leave a comment