Revision History:
         11/08/22   Updated for X-Plane 1200 
         07/20/21   Corrected density_params
         07/23/20   Added Y_QUAD's rotation parameter again
         07/22/20   Reorganized, formatted, and units added
         07/08/20   Updated for clarity
	 03/20/12   Updated for X-Plane 1000
	 12/26/07   Updated for X-Plane 900
	 01/08/06   Updated for X-Plane 860
	 07/19/06   Initial Draft

FOREST CONCEPTS

FILE TYPE AND COMPATIBILITY

A .for file describes how to build 3-d trees out of a texture. Forests are placed in X-Plane by either placing a DSF polygon referencing the .for file or by referencing the .for file in an autogen art asset and placing tree annotations into the autogen tiles.

Starting with X-Plane 12, .for files can be used to define actual 3-d trees made of 3-d mesh. The general placement rules for trees still apply for 3-d trees, but the .for file has been expanded to provide additional ways to describe a tree’s look and behavior.

The forest file is essentially a set of rectangles describing where in the texture each tree resides. Lines starting with a # are comments.

LAYERS AND GROUPS

A .for file defines tree layers. Each layer is identified by an index number, starting at 0 by convention.  When a forest is built in a DSF, trees are placed from each layer, allowing for a multi-layered effect (E.g. underbrush and larger trees).  When trees are placed in autogen, the autogen tile specifies the specific layer it randomly picks a tree from.

Trees in layers may optionally be split into groups. This allows for clustering – with the right randomization parameters, X-Plane can cluster trees from the same group together, creating areas of similar-species trees.  If groups are not used in the .for file, one group is automatically created per layer to hold all trees in that layer.

PERLIN NOISE

In X-Plane 10, some of the randomization for forests can be specified via perlin noise.  The parameters are four pairs of wavelengths (in meters) and amplitudes (a ratio between 0 and 1).  For example:

CHOICE_PARAMS 500 0.75 10 0.25 0 0 0 0

sets up a perlin noise pattern to pick tree groups with the groups mostly changing about every 500 meters.  The second wave with 10 meters and 25% power helps “muddle” the edge of the transitions.  Perlin noise always consists of four wavelength/amplitude pairs; you can set unused amplitude/period pairs to 0,0.

Perlin noise constructs a normalized wave form between -1 and 1.  That is, an amplitude of 1 will maximally modulate between the minimum and maximum height of the trees.

Zero or all of the perlin _PARAMS can be used in the same .for file.

MESH BASED 3-D TREES

Starting in X-Plane 12, .for files have additional support for 3-d trees. Now trees can be either 3-d mesh based trees, or legacy 2D billboard trees. 3-d trees differ from 2-d trees in that they can have up to 3 meshes and up to 4 LOD steps to decrease the amount of detail present. This is necessary to increase performance by reducing visual quality of trees in the distance. A 3-d tree will always have a 2-d billboard tree as its last LOD step to further reduce the amount of computational power required for drawing. As a side effect, even if you only author 3-d based trees, you must still provide an atlas texture for the last LOD step.

Additionally, in X-Plane 12, the material parameters for .for files have been greatly expanded. A .for file now supports the standard X-Plane material commands that can be found in this article: Standard Shading Options for X-Plane 10 Scenery. This is regardless of whether the .for file describes legacy quad trees, or modern 3-d based trees. When providing 3-d trees, .for files have an additional material that will be used. You can switch between materials using the SHADER_2D and SHADER_3D commands. Subsequent commands will change the parameters for either the 2D or 3D shader. By default the 2D shader is active.

The default 2D shader starts out with double sided material and alpha testing with an alpha cut off value of 0.5. This matches the behavior of X-Plane 11 and prior.

FOREST HEADER

A .for file has a standard X-Plane header:

A

800

FOREST

The rest of the .for file contains commands that specify the forest file.

COMMANDS

TEXTURE <filename>

This defines the texture to be used for the forest. The entire forest must be built out of a single texture file. The file name is specified relative to the .for file, just like OBJ8 files. Lit textures are not allowed for forests.

[X-Plane 12] Starting in X-Plane 12, additional material commands are available that also supersede the TEXTURE command. You can find the new material commands here: Standard Shading Options for X-Plane 10 Scenery.

LOD <max lod>

This defines the farthest distance the trees can be seen. Lower values cause forests to disappear faster but result in faster frame rate.

[X-PLANE 9] In X-Plane 9, the LOD command is ignored; X-Plane calculates the viewing distances for all forests based on user settings. X-Plane will attempt to draw the forest for as long of a distance as possible, with a density approaching what is specified in the scenery file.

[X-PLANE 12] In X-Plane 12, the LOD command is no longer ignored. Instead, X-Plane will still calculate a maximum internal rendering distance based on the graphics settings set by the user and use the smaller of the two.

SCALE_X <x scale>

SCALE_Y <y scale>

These define the coordinate scale that is used to define the texture coordinates for the forest. This does not have to be the same as the size of your texture. Basically all texture coordinates are interpreted as if on a texture of these dimensions and then fit to the actual texture. (This command is provided to allow you to easily input numbers read off Photoshop rather than working in fractions.)

SPACING <x spacing> <z spacing>

This defines how far apart the trees are in meters. Smaller numbers pack the forest tighter and cause the sim to run slower (since more trees must be used to fill an area).

RANDOM <x spacing> <z spacing>

This defines how much, in meters, each tree may deviate from a perfect grid filling. So a random of 0 0 means a perfect grid.

TREE <s> <t> <w> <h> <offset> <frequency> <min h> <max h> <quads> <layer> <notes>

Each tree command (there can be more than one) defines a tree. Each tree is defined by a quad in the texture. The parameters are:

  • s – the horizontal texture coordinate of the lower left corner of the rectangle.
  • t – the vertical texture coordinate of the lower left corner of the rectangle.
  • w – the width of the tree texture rectangle.
  • h – the height of the tree texture rectangle.
  • offset – the distance from the left to the center of the tree in pixels.
  • frequency – the percentage of the time this tree is used. The sum of all percentages of all trees must add up to 100%.
  • min height – the minimum height of this tree type in meters.
  • max height – the minimum height of this tree type in meters.
  • quads – the number of polygons used to make the tree (1 or 2)
  • layer – this defines the layer the tree will belong to.  If the tree is within a group the tree layer must match the previous group layer.
  • notes – all further text on the line, used as a comment

Each tree is built from 1 or 2 quads. The texture dimensions define the aspect ratio and texture used. The quads are scaled based on the possible height range. You can specify where the center of the tree is – it doesn’t have to be the center of the texture, allowing for asymmetric trees.

[X-PLANE 9] X-Plane 9 limits the number of quads to two at most, and will reduce a tree to one quad based on distance from the viewer and rendering settings. So the number of quads parameter should be considered a maximum. (X-Plane 9 will not promote a one-quad tree into a two-quad tree.)

SKIP_SURFACE <surface type>

[New to 860:] Starting with X-Plane 860, you can use one or more SKIP_SURFACE directives to tell X-Plane not to put trees down on a certain surface type. The legal surface codes are the same ones allowed for OBJ8 ATTR_hard commands. You can use this command more than once to keep trees off many surface types.

Warning: because X-Plane builds both trees and other scenery types while you fly, in small pieces, you cannot use SKIP_SURFACE to keep trees off of scenery elements that are built during flight. (This is all scenery types except terrain.) For example, if you use SKIP_SURFACE concrete to try to keep trees off of roads, only trees that are “planted” by X-Plane after a road is built will be properly excluded.

Y_QUAD <s> <t> <w> <h> <offset_center_x> <offset_center_y> <y_quad_width> <elevation> <rotation>

  • s – the horizontal texture coordinate of the lower left corner of the rectangle.
  • t – the vertical texture coordinate of the lower left corner of the rectangle.
  • w – the width of the tree texture rectangle.
  • h – the height of the tree texture rectangle.
  • offset_center_x – the pixel offset on the x-axis where the Y_QUAD will sit on the tree trunk
  • offset_center_y – the pixel offset on the y-axis where the Y_QUAD will sit on the tree trunk
  • y_quad_width – the pixel width of the quad, based on the aspect ratio of the UV map
  • elevation – the pixel height, relative to the pixel height of the vertical TREE
  • rotation – rotation in degrees about the y-axis relative to the principal vertical quad

[New to 1000:] X-Plane 10 allows for an optional vertical base quad in a tree. The Y_QUAD directive applies to the previous TREE directive, but horizontal quads will only be created when the tree is built by the autogen system via specific annotations. The UV map is established via a quad (from the lower left corner) – the pixel offset establishes where the tree trunk sits on the 2-d quad.

The tree has a width parameter specifying the width of the quad (the aspect ratio is defined by the UV map) and an elevation for how far off the ground the quad is.  Both of these parameters are described in the unit of pixels of the vertical billboard.  In other words, if the vertical billboard of a tree is 100 pixels tall and you specify an elevation of 15 pixels, the horizontal billboard is always 15% of the way up the tree (whatever its final height is).  The motivation behind using vertical-billboard pixels here is to allow the UV map resolutions of the horizontal and vertical quads to be different; by sizing the horizontal tree in terms of the vertical one, a tree of fixed proportions can be built.

GROUP <layer> <percent>

[New to 1000:] X-Plane 10 can group trees into clusters – the groups should be consecutive in the file.  The layer parameter is the same as the layer of a tree itself – and all trees in a group should share the group’s layer.  The percentage of all groups should add up to 100%.

X-Plane will select trees by group when perlin noise is used, creating forest clusters.  When trees are in a group, the percent occurrence of all trees within a single group should add up to 100%.

DENSITY_PARAMS <amp 1> <dist 1> <amp 2> <dist 2> <amp 3> <dist 3> <amp 4> <dist 4>

[New to 1000:] this changes the pattern of tree density to follow perlin noise.  Note that the density is also affected by the polygon forest density (0-255) in the DSF, so this parameter effectively only changes the shape of trees for partial density forests.

CHOICE_PARAMS <dist 1> <amp 1> <dist 2> <amp 2> <dist 3> <amp 3> <dist 4> <amp 4>

[New to 1000:] this changes the pattern of tree selection to follow perlin noise.  Combined with forest groups, this can be used to organize a forest into tree stands of one group of trees or another.

HEIGHT_PARAMS <dist 1> <amp 1> <dist 2> <amp 2> <dist 3> <amp 3> <dist 4> <amp 4>

[New to 1000:] this changes the randomization of height from truly random tree height variance to perlin noise, which can create clusters of height changes.

NO_SHADOW

[New to 1005:] this disables shadow casting for the forest.

TREE2  <s1> <t1> <w> <h> <sw> <percent> <min_height> <max_height> <nominal_height> <lod_far> <quads> <type> <notes>

[New to 1200:] like the TREE command, but it has 2 additional parameters. Nominal_height is the height of an unscaled tree. This is used to scale 3-d trees and billboard trees to the same height. Lod_far works just like the LOD command, but is specific to this one tree instead of overriding the far LOD globally.

MESH <name> <lod near> <lod far> <vcount> <idx count> <bend_scale> <max_displacement> <displacement_speed> [<NO_SHADOW>]

[New to 1200:] Starts a new 3D mesh with the given name. The near and far LOD values are the LODs for when to show and hide the mesh. X-Plane will blend between multiple LOD steps, but will always have the mesh fully faded in when lod_near meters away from the camera and fully faded out when lod_far meters away from the camera.

vcount and idx count are the number of vertices and indices in the 3D mesh, which will have to be specified using the VERTEX and IDX commands directly following the MESH command.

Bend_scale, max_displacement and displacement_speed are all parameters used to implement bending in the wind for 3-d trees. The bend_scale is the scalar value for the overall bendiness of the tree: at 0.0 the tree will resist bending in the wind completely. The max_displacment is the maximum amount of horizontal displacement the tree will experience while the displacement_speed is a scalar on the wind speed, which can be used to make trees that are resistant to bending in small wind speeds.

The NO_SHADOW parameter can be optionally defined and will prevent a mesh from casting shadows. This is useful when building small clutter objects with the vegetation system without increasing the computational burden too much. Please note that the .for file system is NOT suited to implement lots of ground clutter objects or grass systems, and performance and VRAM usage will suffer as a consequence. Small meshes are not well suited for the forest system!

VERTEX <x y z n n n s t w w w>

[New to 1200:] Must come after a MESH command and defines a vertex of the tree. xyz is the vertex position, nnn is the normal and s t is the UV coordinates of the texture used by the 3D material. The w w w parameters specify additional vertex weights that affect the displacement, branch attenuation and tree phase in that order.

The displacement value is single scalar defining how much the vertex is affected by the overall displacement of the tree. Leaves and branches tend to have high value for the overall displacement while the trunk tends to have a smaller displacement value.

Branch attenuation is the amount of flutter the vertex experiences in its movement in the wind. This value should be quite high for leaves and very close to or 0 for branches and the trunk.

Phase is the overall phase of the wind animation. Since the animation is derived computationally, giving different branches and leaves a different value here will make it so that the whole tree doesn’t move as if it were a single object.

IDX <n …>

[New to 1200:] Must come after a MESH command. Describes the index of the vertex to be used. More than one index can be specified at one time.

MESH_3D <name>

[New to 1200:] Must come after a TREE or TREE2 command. A single tree always starts with a TREE or TREE2 command describing the overall parameters of the tree. When followed by one or more MESH_3D parameters, the tree becomes an X-Plane 12 style 3-d tree. Each MESH_3D command defines an additional LOD step.

In practice your file will look something like this:

MESH foo_name …

VERTEX …

IDX …

TREE2 …

MESH_3D foo_name

SHADER_2D

[New to 1200:] Subsequent commands will affect the 2D shader.

SHADER_3D

[New to 1200:] Subsequent commands will affect the 3D shader.

EXAMPLE FILE

A

800

FOREST

# Conifer cold wet

#This tells us the bitmap that will be used for these trees.

TEXTURE forest.png

#This tells us how far away trees disappear – in this case 5 km.

#(This is a bit too soon – 10 km or 20 km looks better.)

LOD 5000

#This defines the texture size for the coordinates given below.

SCALE_X 1024

SCALE_Y 1024

#Tree spacing: place a tree and shrub every 20 meters.

SPACING 50 50

#Vary their placement by up to 10 meters in any direction.

RANDOM 20 20

#low-left coord tex size center percentage    —-height—-

# tree  s         t         w         y         offset occurrence            min          max          quads         type         name

#—————————————————————————————————

TREE         44        896        52        127        25        12.5                10        28        1        1        connifer 1

TREE         194        896        44        127        22        12.5                10        28        2        1        connifer 2

TREE         238        896        65        127        32        12.5                10        28        1        1        connifer 3

TREE         443        896        66        127        33        12.5                10        28        2        1        connifer 4

TREE         584        896        77        127        39        12.5                10        28        1        1        connifer 5

TREE         712        896        62        127        32        12.5                10        28        2        1        connifer 6

TREE         777        896        61        127        29        12.5                10        28        1        1        connifer 7

TREE         840        896        72        127        36        12.5                10        28        2        1        connifer 8

SKIP_SURFACE water