Howto:Regional texturing

From FlightGear wiki
Revision as of 09:07, 9 April 2016 by Thorsten (talk | contribs)
Jump to navigation Jump to search
WIP.png Work in progress
This article or section will be worked on in the upcoming hours or days.
See history for the latest developments.

The Flightgear terrain is created in a largely automated process from a large amount of geodata. The outcome may not necessarily always look like a region appears in reality. Regional texturing is one of the most powerful tools available to improve the visuals and get a result much closer to reality.

Background

Terrain data structures

Tnternally, the terrain is a dense mesh of triangles which determine the elevation at each given point. However, the mesh also encodes what a patch of terrain is supposed to represent by assigning a so-called landclass to a triangle. Landclasses are a concept that is directly inherited from geo databases like CORINE. For instance, the database may tell that a certain patch of terrain is 'Shrubcover'. This information is stored with the terrain mesh.

Flightgear then uses it in-sim in several ways: First, the landclass of a triangle determines how it appears, i.e. what texture and/or effect are assigned. Second, it also determines FDM-relevant properties, for instance whether it will yield when you try to land on it (for instance water), whether you can roll across it, how bumpy rolling will be, and so on. The Advanced Weather system uses the landclass to determine the likelihood of convective cloud formation when the sun heats the terrain. Finally, also the distribution of random overlay objects (such as the density of lights at night or the number of trees or buildings appearing) is also determined by the landclass.

A separate layer for the terrain are static objects which are placed on definite positions onto the mesh by other means - for their placement, no landclass information is used and while they can be placed 'onto' the mesh automatically, they can also be placed to absolute altitudes.

Regional texturing specifically changes the appearance of a landclass and also the placement of overlay objects - it is not a technique capable of altering the outlines of landclasses in the mesh. In other words, using the technique you can make an existing patch of shrubland look more realistic, but you can not change part of a lake that has the wrong shape to be shrubland.

Control files

The central file responsible for the assignment of textures etc. to landclasses is /Materials/regions/materials.xml (for historical reasons, there are two alternative schemes under /Materials/default/materials.xml and /Materials/dds/materials.xml which are not supposed to be modified by regional definitions). They can be selected in-sim in the rendering dialog.

materials.xml largely serves as an index to include the actual regional definitions. However, hierarchy is important and needs to be considered: Later valid definitions always override earlier definitions. So for instance in texturing Honolulu, Hawaii, first global-summer.xml is considered (which is the world-wide default for summer textures), then the content of hawaii.xml overwrites the global definitions and finally the content of oahu.xml overwrites part of the Hawaii-specific definitions. The wrong order of files can lead to definitions not being used.

Each specific region file has to contain a name, at least one (possible more) area definitions and may contain a condition. The header of the Hawaii region for instance is

  <name>Hawaii</name>
  <area>
    <lon1>-179.0</lon1>
    <lon2>-154.0</lon2>
    <lat1>18.8</lat1>
    <lat2>28.5</lat2>
  </area>

  <condition>
    <equals>
      <property>sim/startup/season</property>
      <value>summer</value>
    </equals>
  </condition>

The area tags define rectangles in coordinates - if FG requests a scenery tile to load, and the coordinates of the tile are within the area defined and the condition is met, the landclass definitions of the file are used for the scenery. It follows that regional areas have the minimum size of a scenery tile (dependent on the location in the world, typically a few tens of kilometers).

In practice the condition is used to switch between the summer and winter texture schemes - whether it makes sense to allow the user to select winter textures for Hawaii is in the eye of the beholder.

In each definition file, what follows are the assignments of landclasses to materials, and condition and area holds for all of those in the rest of the file.

Material definitions

Let's take a look at a single block of material definitions:

  <material>
    <name>BarrenCover</name>
    <name>Dirt</name>
    <name>OpenMining</name>
    <name>Rock</name>
    <name>Dump</name>
    <texture-set>
      <texture>Terrain/rocks-lava.png</texture>
      <texture n="12">Terrain/rocks-desert.png</texture>
      <texture n="14">Terrain/rock_grain01.png</texture>
      <texture n="13">Terrain/void.png</texture>
    </texture-set>
    <parameters>
      <grain_strength>0.7</grain_strength>
      <transition_model>0.0</transition_model>
    </parameters>
    <xsize>1000</xsize>
    <ysize>1000</ysize>
    <solid>1</solid>
    <friction-factor>0.9</friction-factor>
    <rolling-friction>0.1</rolling-friction>
    <bumpiness>0.3</bumpiness>
  </material>

The first tags are name - they contain a list of landclasses the material refers to (remember that the landclass is stored with the terrain mesh, i.e. the mesh contains the information that a certain triangle is 'Rock').

The next block is the texture set assigned to the landclass - it contains the name of the files to be used for the visuals (to make use of Procedural Texturing techniques, usually multiple textures are assigned). The parameters block allows to configure procedural techniques by passing control parameters to the Shader generating the composite texture.

<xsize and ysize are important because they determine how large a patch the base texture file is supposed to cover (in the above example, 1000 m x 1000 m is covered by one texture sheet, if the sheet is 1024x1024 pixels, the base resolution is about 1 m).

The final set of parameters is passed to the FDM for ground interactions - we learn that 'Dirt' and 'Rock' are to be treated as solid surfaces and what their rolling friction and bumpiness is supposed to be. Using blocks like this, every landclass as stored in the terrain mesh is assigned characteristics that determine how it looks and behaves in FG when the scenery tile is loaded.

Note that using material definitions it is possible to merge different landclasses - in the above example triangles classified as 'Dirt' and 'Rock' will look and feel the same - but making two separate definitions instead, they could also be made to look differently. Again, a single landclass can not be made two different materials in the same region - later definitions will overwrite earlier ones.

Basic workflow

To make a regional texture definition for a region then, you need to

  • define a region by creating a file with a name, area and condition header
  • include this file in materials.xml
  • fill it with individual material definitions which are supposed to apply to the region

For the latter task, you may or may not have to

  • acquire suitable textures for the region
  • configure the procedural texturing parameters to generate good composite textures
  • assign random trees, buildings, materials, lights,...
  • assign surface properties

Creating good textures

Good terrain texturing is more of an art than of a science, because there are many different factors to consider.

What makes a good texture sheet?

To get visuals of a region close to reality, you might want to start with aerial imagery of the regions and extract textures from there - but that is not without pitfalls.

The texture needs to be GPL compatible. While there are some public-domain aerial imagery data bases, the most popular (Google Earth) is not. I've also made surprisingly good experience in looking for aerial imagery from local photographers and asking their permission to extract a texture from their work.

The biggest problems of textures are too much structure and lack of structure. If there is lots of structure in a texture, once you map the same sheet to a large area you get pronounced tiling:

Tiling in agriculture

Tiling like this is very prominent from high altitude, it is one of the visually least appealing features and should be avoided at all cost. If the base texture layer has much less structure, tiling is also much less apparent:

An example for texture tiling

On the other hand, the more the structure inside a texture sheet is de-emphasized, the more prominent is also the appearance of the landclass boundaries where the texture sheets change:

An example for landclass seams

The ideal texture sheet is a compromise between these two extremes - structured enough to de-emphasize landclass boundaries, not so structured as to lead to bad tiling.

Another thing to consider when extracting a texture from aerial photography is that the land may be often dusty on the photograph. That is problematic because in FGs texturing scheme we want to be able to add dust procedurally which only works if the base texture is sufficiently clean.

So you may have to work with an image processing software to adjust hue and contrast of a texture sheet after taking it from a photograph, and run a mapping algorithm to make sure it does not generate seams when repeated.

Understanding the toolkit

Procedural Texturing is the primary tool to counter texture tiling. It works by generating structures from a non-repeating noise function and gives compelling results for both natural landclasses

Removal of tiling

and agriculture

Overlay de-tiling in agriculture

and in addition allows to generate a very high resolution in the centimeter range close to the ground. Basically if you understand and use procedural techniques, even for textures with lots of structure tiling ceases to be a problem and you can focus on dealing with the landclass seams.

One factor to consider is hue blending. If you look at real aerial photographs of a region, you'll notice that soil has the same color everywhere. For instance, North Carolina has a fairly reddish soil. You see that color on bare patches of grass, but also on forest clearings, in gardens - everywhere. Because it's the same soil everywhere. Similarly, vegetation tends to have the same hue in a region, regardless of whether it is in a suburban garden or in the countryside.

Now consider texturing the shrubland of a region with olive green vegetation on reddish patches of soil - and then the suburban regions with ochre soil and lush bright green vegetation - the result is an obvious visual mismatch.

Compare this scene of the French Alps with multiple different hues of green and ground

Lack of hue blending.

with a hue-blended scene of the same scenery:

Lack of hue blending.

to see just how important hue blending is. Procedural overlay texturing techniques are an excellent tool to do such blending, because they allow e.g. to keep the base texture the same across two landclasses and only vary the overlay layers to mark a landclass as different. Usually it is much better to use hue-blended texture sheets than to use the 'right' sheets when there is high contrast between landclasses which is not always there in reality.

By the way, do not aim to remove all vector seams - some of them are there in reality, for instance patches of managed forest in central Europe are characterized by very sharply pronounced boundaries, and so are suburban regions. Aim to de-emphasize only those that have no equivalent in reality.

Assigning effects

Currently (as of April 2016), Flightgear supports three different rendering schemes, the classical renderer, Project Rembrandt and Atmospheric light scattering (ALS).

While ALS has per default support for procedural texturing, the other two have not and support only a limited range of effects which has to be assigned. For that reason, the focus of most regional texturing has been on creating ALS procedural definitions, but care has to be taken to create visuals which work for the other renderers as well.

In addition, some situations require also in ALS to assign a special effect because the default terrain effect is ill equipped to handle the visuals (water and urban relief mapping are the prime examples, but there's also the procedural rock shader or the agriculture shader).

Technically, effects are assigned inside a material definition with a tag like

    <effect>Effects/forest</effect>

Usually the assignment between ALS-supported effects and effects of the other frameworks is made to be unproblematic:

  • assigning an effect like forest of the default rendering framework is ignored by ALS
  • assigning ALS supported effects like water or agriculture automatically selects the corresponding classic and Rembrandt effects (water and crop in that case)
  • ALS effects usually rely on texture set definitions like
   <texture-set>
      <texture>Terrain/deciduous-hires.png</texture>
      <texture n="12">Terrain/shrub-hawaii.png</texture>
      <texture n="13">Terrain/shrub-hawaii.png</texture>
    </texture-set>

all the higher index numbers (here 12 and 13) are ignored by the classic renderer and Rembrandt and exclusively used by ALS. It should therefore not be a problem to create a materials definitions which work for all renderers without clashes.