OpenGL Terrain Renderer
Chunk based system
My submission for the Graphics Programming 3 course of the International Game Architecture and Design study program at NHTV University. The original assignment required us to render a square textured terrain using a heightmap. Because I was invested in playing MMORPG's at the time, I decided to try implement a large scale openworld terrain.
The terrain system uses a chunk based system, where one chunk is 256 by 256 meters in size. These chunks are culled depending on the camera position and view frustum. The chunks get loaded one chunk per frame to prevent hickups during fast camera movement, where the chunks closest to the camera get loaded first.
In order to reduce the total triangle draw count I implemented a derivative of the Continuous Distance-Dependent Level of Detail algorithm (link below). This algorithm doubles the size of the triangles based on the three-dimentional distance to the camera, effectively halving the amount of triangles per step. The smaller triangles then morph into the bigger triangles over distance by merging the even number vertex with its odd number neighbour.
A single terrain chunk is made up of three components; a heightmap, a colormap and a texturemap. The heightmap simply indicates the height of the terrain, which is stored in a 256 by 256 image containing floats. The colormap is superimposed on the terrain, which is a 256 by 256 8bit RGB image. This allows for adding extra contrast and color to the basic terrain, and can be used to add extra details, like blood in snow, without having to add an extra blood texture. Finally, the terrain receives four texturemaps (or splatmaps), which contain the weight of the textures. Each texturemap is stored in 1024 by 1024 8bit rgba textures, using each channel as a weight, allowing for a maximum of 16 textures. Each terrain chunk can then be assigned a palette of 16 textures, so that each chunk can use different textures.
The terrain uses a special method of terrain blending, where the weight of elements in the texture can be emphasized using the alpha channel in the texture.
Above rock texture puts a heavy weight on the rocks and a low weight on the space between. Assuming that the grass texture's weight is between these two levels, it will prioritize rocks over grass. This allows a sand texture to fill up the cracks between rocks for example, adding a very nice transition between different terrain types.
|OpenGL 4 (C++, GLSL)