Tag Archives: Rendering

Terrain :: Geometry

The Terrain for SeganX engine is going to be completed. in this post, I will describe the geometry algorithms I used for rendering the terrain briefly. my approach to designing this feature was easy to use, simple, and straightforward to implement. Artist/Level designer can easily:
– create geometry everywhere and every amount that was required.
– increase performance by implementing LOD and patching geometries to reach minimum draw call.

As I mentioned before, everything in the scene is a kind of node member (Component). In this method, the terrain is like the other members ( mesh, particle, sound, … ). The terrain is a node member too. Thus for importing terrain to the scene, we must create terrain attach it to the node, and then add the node to the scene. so we can create any number of terrain and add them to the scene. But to reach the goals mentioned above I designed terrain members with some more information.

Geometry data
Each terrain member has a fixed 33×33 vertices placed in grid style. I chose this size because I want to generate 6 levels of detail. With 33×33 vertices we have 32×32 quads for the first level. This means if we half each level 6 times, finally we will have one quad for the lowest level of details. Choosing vertices for each level will be done by using 6 static fixed-size LOD structures called TerrainLOD that are used for all Terrain members. Thus, there is no need for more indices/vertices for each level and we just choose a correct LOD structure depending on view distance. So for rendering all terrain members, I used a big buffer and appended to that big buffer vertices of all terrain members in the view port. The appending process is just applied on vertices which are described in the LOD structure. Finally, the terrain will be drawn by one draw call.

T-junction problem
T-junction problem appears between terrain blocks with different LODs and makes terrain ugly. The picture below illustrates this problem clearly:

T-Junction between LODs

There are several ways to remove these junction problems. according to the ‘Geometry Data’ of terrain in the engine I defined and implemented a simple structure to describe indices for each LOD. this structure splits indices for each LOD into 9 parts:

typedef struct TerrainLOD
{
    TerrainChunk    center;         //  standard center
    TerrainChunk    sideFUL[4];     //  standard 4 sides
    TerrainChunk    sideLOD[4];     //  simplified 4 sides
}
*PTerrainLOD;

Indices of center in this structure contain polygon indices that cover the center except for 4 sides “up, right, down, left”. these sides will covered by sideFUL or sideLOD. sideFUL contains indices to cover all polygons in that LOD and sideLOD contain simplified indices.

Choosing which side ( sideFUL or sideLOD ) to use as indices is simple. we can easily predict the LOD of neighbors. to predict the LOD of each neighbor I compute the neighbor’s position by adding fixed terrain size to the current position. By putting this position to some special functions we can get the neighbor’s LOD number depending on current camera properties. for each neighbor that uses fewer details, we append sideLOD to the big buffer, otherwise, we use sideFUL. here is a screenshot for terrain in wireframe mode :

Terrain rendering in SeganX engine

My next task is choosing and implementing a terrain material system. The current system supports multilayer material systems. but implementing brush, and gathering information about each brush on terrain to increase performance, optimization and optimization and optimization still need more and more and more work. but now I have to spend more time on to Rush for Glory game project.