Terrain is an important component in 3D game. A texture is used to stand for the
height map. And up to 4 textures can be used to blend the details of the terrain,
grass, road, and so on.
HeightMap objects are the core of the terrain. Different from the common image
the height map represents the height of vertices. It determines the terrain's
DetailMap objects are a list of textures determining the details of the terrain,
up to four textures can be used.
AlphaMap objects are an image whose data is the blend weights of detail maps.
The blending result is the final terrain's appearance.
Terrain uses an optimization technique called Level Of Detail or LOD.
This is a rendering technique that reduces the number of verticies (or triangles)
that are rendered ,for an object, as its distance from camera increases. Users
can set the distance to the
Camera by calling the
Terrain::setLODDistance(float lod1, float lod2, float lod3) method.
Neighboring chunks of
Terrain objects, which have different LOD may cause
the crack artifacts.
Terrain provide two functions to avoid them:
Terrain::CrackFixedType::SKIRT will generate four, skirt-like meshes at each edge of the chunk.
Terrain::CrackFixedType::INCREASE_LOWER will dynamically adjust each chunks indices to seamlessly connect them.
How to create a terrain
Terrain takes a few steps. Example:
The following code snippet is creating a player and place it on the terrain:
auto player = Sprite3D::create("chapter9/orc.c3b"); player->setScale(0.08); player->setPositionY(terrain->getHeight(player->getPositionX(),player->getPositionZ()));
- create all
DetailMapobjects (up to four), you need pass the
DetailMapobjects to the Terrain::DetailMap struct:
Terrain::DetailMap r("dirt.dds"); Terrain::DetailMap g("grass.dds"); Terrain::DetailMap b("road.dds"); Terrain::DetailMap a("greenSkin.jpg");
- to create a
TerrainDatavariable with detail maps, you need to specify the terrain's height map file path and alpha map file path:
Terrain::TerrainData data("chapter9/heightmap16.jpg","TerrainTest/alphamap.png", r, g, b, a);
- pass the
TerrainDataobject to Terrain::create, the last parameter determines the LOD policy (as talked about above). Example:
_terrain = Terrain::create(data, Terrain::CrackFixedType::SKIRT);
- If you set a
Terrainobjects camera mask and add it to a
Scene, be careful. When
Terrainis added into a
Scene, you can not use transform(translate, scale) on it anymore. If you do this after calling addChild(), some of the terrain's methods may calculate wrong results.
Get Terrain Height
Use the method Terrain::getHeight(float x, float z, Vec3 * normal= nullptr) to
get the specified position's height. This method is very useful when you want to
Sprite3D object or any
Node on the terrain's surface.
Ray-Terrain intersection test
A Ray-Terrain intersection test will calculate the intersection point by giving a specified position.
Terrain::CrackFixedType::SKIRT will generate four skirt-like meshes at each chunks edge.
Terrain::CrackFixedType::INCREASE_LOWER will dynamically adjust each chunks index to seamlessly connect them.