Virtual Planet Builder

From FlightGear wiki
(Redirected from VPB)
Jump to navigation Jump to search

VirtualPlanetBuilder (VPB) is an OSG tool that generates native OSG data to represent terrain, usually by draping a GEO-TIFF over an elevation model.

Building VirtualPlanetBuilder

The VPB project and code can be found here:

There is now[1] a VPB docker This is a link to a Wikipedia article container for Linux: and

If you've got an existing FlightGear build, there are some additional dependencies:

  • OSG
    • Including NVTT. ('sudo apt-get install libnvtt-dev' - oddly VPB builds without it but then checks for the shared library at runtime...)
  • GDAL (, Note that this needs to 2.4.X
    • ... which requires PROJ 6 or above (
      • ... which requires the sqlite3.11 or above development package (on linux - 'sudo apt-get install libsqlite3-dev')

Note that GDAL and PROJ do not use cmake, so it builds in the source directory as follows:

./configure -prefix=/path/to/install

VPB is built using cmake e.g.

cmake -DOSG_DIR=/path/to/OSG/install /path/to/VPB/src

Getting Landcover Data

For CORINE data covering Europe, try here:

For US National Landcover Database (NLCD) try here:

ESRI (akak Sentinel-2) covers the entire world but with fewer distinct landclasses:

Choose RASTER data, which will download a geo-referenced TIF image.

Note that the mapping from landcover to materials is performed in Materials/base/landclass-mapping.xml, and currently only maps CORINE raster landclasses. If you have another landcover source (e.g. the US NLCD. ESRI), you will need to use your GIS (Grass, QGIS) to convert them such that the raster uses the correct landclass indexes.

Using Vector Data

If you wish to create higher resolution scenery, you may need to convert from vector data.

Key points:

  • If required, re-project to WGS84. Ensure you project and layer are in the same projection.
  • Map the vector polygons to have the correct landclass. In QGIS, you can do this as follows:
    • Open the Attribute Table
    • Create a new field (c_index) with type int
    • Open the field calculator the update the new field (c_index) using a calculation that maps from the landclass fields in your data. For CORINE vector data this is the c18 field. An example is below, and some mappings are available here:
WHEN c18=111 THEN 1
WHEN c18=112 THEN 2
WHEN c18=121 THEN 3
WHEN c18=122 THEN 4
WHEN c18=123 THEN 5
WHEN c18=124 THEN 6
  • Use a rasterize command to create a raster:
gdal_rasterize -l CORINE_Modified_WGS84 -a Landclass -ts 35000.0 33300.0 -a_nodata 48.0 -te 3.0 51.0 8.0 54.0 -ot Byte -of GTiff -co COMPRESS=NONE -co BIGTIFF=IF_NEEDED /home/stuart/FlightGear/VPB/data/Modified/CORINE_Modified_WGS84.gpkg /home/stuart/FlightGear/VPB/data/10m/Netherlands2.tif

Getting DEM data.

The most commonly used Digital Elevation Model used is SRTM.

SRTM with 90m resolution is available here:

SRTM with 30m resolution is available here: (Directory , Interactive search by selecting areas or points: example . To download you need a free account from here)

VPB accepts both raster and HGT files.

LoD, Mesh size and Framerate

Unlike WS2.0 which has a fixed terrain mesh, VPB uses different terrain meshes with different level of detail (LoD) depending on the distance of the viewer from the particular piece of terrain.

Simplified diagram of different LoD tiles being loaded as an aircraft gets closer.
Diagram showing how the Virtual Planet Builder filenames are built for each LoD level. Note that this just shows 3 LoD Levels. Our scenery goes to "L5".

Virtual Planet Builder provides a variety of settings that have a big impact on the eventual terrain mesh. The two main settings (the number of LoD levels, and the ratio of the LoD radius and maximum visible range), have a huge impact on the number of vertices, how the terrain looks, LoD "popping", and framerate.

To attempt to understand the relationship, a test was performed. WS30 terrain was generated for a 2x2 degree section of the European Alps bounded by (7E, 45N), and (8E, 47N), with settings as listed below. FlightGear was then run on a desktop with an NVidia GeForce GTX 1660 with 6GB of VRAM. The system appeared I/O limited as GPU utilization was around 30% and on 2GB of VRAM was used.

The following commandline options were used to place the ufo just to the NE of the Matterhorn, facing SW.

--aircraft=ufo --timeofday=morning --disable-real-weather-fetch --disable-ai-traffic --disable-random-objects --disable-random-vegetation --altitude=15000 --prop:/scenery/use-vpb=true --disable-sound --disable-ai-models --prop:/sim/rendering/texture-cache/cache-enabled=false --lat=46.021023 --lon=7.728291 --altitude=12662.75 --heading=226.0 
Experimental results varying LoD Level and visibility distance ratios
Dem Resolution LoD Levels Radius to max visible distance ratio Lowest LoD Radius (km) Highest LoD Range (km) Lowest LoD Range (km) Vertices in view Triangles in view (M) Framerate (M) Frame Latency (ms) Terrain Size (MB)
90 8 7 0.6 1099 4.3 15 30 28 40 128
30 8 7 0.6 1099 4.3 32 61 19 59 425
30 7 5 1.2 785 6.1 5.6 11 75 17 170
30 7 3 1.2 475 3.7 3 6 105 14 170
30 6 5 2.5 785 12 4 7 115 13 (a) 80
30 4 5 9.8 785 49 3 6 125 12 (b) 25


(a) - Using these settings there was a noticeable reduction in apparent heightmap resolution with a 30m DEM, probably because the resolution of the lowest LoD level was ~40m, compared with 20m for an 7 LoD level mesh.

(b) Using these settings, the terrain resolution was unacceptably poor.

These results suggest that using 7 LoD Levels and a radius of "3" will provide a good balance, with high terrain quality and good frame-rate.

Running VPB

FlightGear expects scenery in 1x1 degree tiles in a slightly different format to WS2.0. The scenery needs to be in a "vpb" directory, followed by a directory structure similar to WS20 (10x10, then 1x1 degree directories), with the final file being a 1x1 degree section with a "ws_" prefix, and in the ".osgb" format. E.g. vpb/w010n50/w004n50/ws_w004n50.osgb

VPB is available in a docker image here. Instructions on how to install and use it can be found in Howto:Create WS3.0 terrain.

Here are the options I've used to generate some scenery of the UK:

./bin/osgdem --TERRAIN \
--image-ext png
--no-interpolate-imagery \
--disable-error-diffusion \
--geocentric \
-t /home/stuart/FlightGear/VPB/data/CORINE/u2018_clc2018_v2020_20u1_raster100m/DATA/U2018_CLC2018_V2020_20u1.tif \
-d /home/stuart/FlightGear/VPB/data/SRTM90/srtm_34_02.tif \
-d /home/stuart/FlightGear/VPB/data/SRTM90/srtm_35_01.tif \
-d /home/stuart/FlightGear/VPB/data/SRTM90/srtm_35_02.tif \
-d /home/stuart/FlightGear/VPB/data/SRTM90/srtm_36_01.tif \
-d /home/stuart/FlightGear/VPB/data/SRTM90/srtm_36_02.tif \
-b -4 50 -3 51 \
--PagedLOD \
-l 7 \
--radius-to-max-visible-distance-ratio 3 \
-o vpb/w010n50/w004n50/ws_w004n50.osgb
  • --TERRAIN to use osgTerrain::Terrain database
  • --compressor-nvtt --compression-quality-highest to generate native DDS mipmaps
  • --geocentric because that's what FG uses
  • -t the texture to drape (in this case CORINE)
  • -d the DEM to use (in this case pieces of SRTM90)
  • -b is the extents in decimal degrees: LON1 LAT1 LON2 LAT2, in this case from (-4,50) to (-3,51)
  • --PagedLOD to generate PagedLOD nodes
  • -l 4 the number of LOD levels to generate. At the equator, a 1x1 degree tile has a 157km diagonal. The LoD follows a quad-tree like structure, with each LOD level having 4 sub-tiles in a 2x2 array. If we want our smallest tile to have a ~10km diagonal, we need 4 LoD levels
  • --radius-to-max-visible-distance-ratio is self-explanatory. We want the lowest level of LoD to be visible 20km away, so a ratio of 5 is appropriate.
  • -o is the output file, in this case native OSG binary format. FG expects WS3.0 data in a vpb subdirectory, with the structure shown.