I am looking from moving from a pure 2D map to making it 3D with a height map, currently using D3D11. My initial goal being something like Stronghold or Railroad Tycoon 2, keeping my existing 2D assets, but I want the scope to replace those with 3D ones and full camera movement later (shallow camera angles being the main issue, due to the resulting long view distance).
The problem I am having is determining the best/correct approach to render this terrain. A quick test showed me that just having a 1000x1000 tile 2xtriangle quad list doesn't perform (4 million vertices, 6 million indices, and about 50fps on my AMD 7870 with just that one DrawIndexed D3D11 call).
I have various ideas for enhancing this, of various complexity, but don't really have any idea which is a suitable one, or if I am missing something simple on this matter.
- Convert the list to a strip. I expect this to be a fairly good gain, with around half as many vertices for the vertex shader, and will likely do it. Need to work around some complexities (e.g. Stronghold style cliffs, and vertex texture fields), and it doesn't really seem enough by itself, would only expect at most that 2x performance boost.
- At longer distances from the camera, only render a single quad for multiple tiles (average height, most common tile texture, etc.). This however seems to force me to re-create the mesh each frame, and need a way to deal with the edges between detail levels (to support a shallow camera angle, since some tiles are very close, and others distant)? Done/seen this in plenty of games/engines with independent meshes, but not encountered this single mesh issue before (in all of them I did technical stuff with, I found they used pre-made low detail versions of the models to just swap between).
- For larger maps, making sure to only ask D3D to draw ranges I know are in the view area, either with a dynamic mesh, or just making multiple Draw calls for the needed subsets. Essentially this is what I have always done in 2D with a dynamic vertex buffer, but there I only had at most maybe 100x100 on-screen tiles so only a small per-frame buffer, and its trivial to determine the viewable area (x/y tile rect for a simple for loop).