API

Dynamic Terrain Examples

FreeCamera on the Ground

In this example, our player moves on the ground: a character walking, a car driving, or anything else you might find in an FPS game.
The camera used is a FreeCamera. It stays on the ground while moving forward, backward, to the right, or to the left.

Let's create a simple data map with a sine/cosine function:

// map creation
const mapSubX = 100;
const mapSubZ = 100;
const mapData = new Float32Array(mapSubX * mapSubZ * 3);
for (let l = 0; l < mapSubZ; l++) {
for (let w = 0; w < mapSubX; w++) {
mapData[3 * (l * mapSubX + w)] = (w - mapSubX * 0.5) * 2.0;
mapData[3 * (l * mapSubX + w) + 1] = (w / (l + 1)) * Math.sin(l / 2) * Math.cos(w / 2) * 2.0;
mapData[3 * (l * mapSubX + w) + 2] = (l - mapSubZ * 0.5) * 2.0;
}
}

The hills have a different height depending on their positions on the map.

Let's then create a dynamic terrain from this map:

// terrain creation
const terrainSub = 50;
const params = {
mapData: mapData,
mapSubX: mapSubX,
mapSubZ: mapSubZ,
terrainSub: terrainSub,
};
terrain = new BABYLON.DynamicTerrain("terrain", params, scene);

Now we can set the camera altitude on each frame at a fixed elevation above the terrain. For this, we use the method getHeightFromMap(x, z), which returns the height (y coordinate) of the terrain at the given location (x, z).

const camElevation = 2.0;
const camAltitude = 0.0;
scene.registerBeforeRender(function () {
camAltitude = terrain.getHeightFromMap(camera.position.x, camera.position.z) + camElevation;
camera.position.y = camAltitude;
});

If we move the camera with the keyboard arrow keys, it will follow the terrain ground.

PG: Dynamic Terrain

We could also make a bigger map and a bigger terrain :

const mapSubX = 500;
const mapSubZ = 300;
const terrainSub = 100;

As the player stays on the ground, they can't see very far into the distance, so we can choose to update the terrain only after 8 map quads have been crossed on either the X axis or the Z axis:

terrain.subToleranceX = 8;
terrain.subToleranceZ = 8;

The terrain is then updated less often. This leaves more CPU time to manage player behavior and everything that can happen or move in the nearby area.

Finally, we could also choose to extend the visible size of the terrain by setting some LOD in the distance.
For example, LODLimits = [4, 3, 2, 1, 1] would mean that:

  • the initial LOD factor (default 1, the one at the camera location) is incremented for all the terrain quads under the 4-th perimetric rows and columns, so it's 1 + 1 = 2 for them,
  • it's incremented once again for all the terrain quads under the 3-th perimetric rows and columns, so it's 2 + 1 = 3 for them,
  • it's incremented once again for the ones under the 2-nd rows and columns, so it's 4 for them
  • it's incremented finally twice, because there are two 1 in the array, for the quads under the first rows and columns, so 3 + 2 x 1 = 5 for those last ones.
terrain.LODLimits = [4, 3, 2, 1, 1];

Let's not worry if this feature seems complex to understand, and just remember that it extends the visible size of the terrain on its perimeter while reducing the rendered map details at the same time.

PG: Dynamic Terrain