As described in my last post, I'd like to create a homegrown system for rendering large terrains. The basic idea is to use a set of planar mesh patches that are displaced in the vertical using a heightmap in the shaders, and using OpenGL 4's tessellation features to create a more detailed and optimally structured mesh during run-time. Also mentioned before was the fact that this might be a bit of trial and error, so bear with me, and if you see me running in the wrong direction - please let me know!
Mesh patches
To displace a mesh in the shaders I first need a mesh... I use an approach similar to the one described by http://developer.nvidia.com/GPUGems2/gpugems2_chapter02.html, but with a simpler patch structure. The basic idea of using such patches is to 1) use a small set of static vertex buffers to keep memory consumption and required CPU-GPU bandwidth low, and 2) to allow patches to be culled. Since the final mesh struture will be determined later on in the tessellation shaders, I think I don't have to be overly concerned with the patch structure. It only has to provide a good enough base for later tessellation, and to potentially cover a large terrain. I will use an arrangement like this:
So there will be just one base patch, scaled and moved around to create a concentric ring of meshes centered on the viewer. Since I am using the Model:Instance() call, and Leadwerks 3.1 by default uses hardware instancing, this should mean that the terrain will actually be rendered in a single draw call (am I right here?). The innermost level (Level 0) is comprised of 4x4 patches with the highest resolution, while every higher-numbered level consists of twelve patches that are double the size of the next lower level (as seen by the grid structure in the lower left). There are three parameters to control the terrain generation:
- Patch size - the number of quads per side in a patch, so a value of 8 results in an 8x8 patch
- Total terrain size - the size of terrain in Leadwerks units (usually meters)
- Quad size level 0 - the size of a quad in Leadwerks units
Using those values, the number of required levels is calculated, afterwards the quad size for level 0 is recalculated to make sure the numbers match. It is probably best to use powers of two for those numbers to reduce the possibility of rounding errors, which might result in vertices on the boundaries not lying on top of each other (e.g. 8 - 4096 - 1).
Code, issues to solve
I have attached the code for generating such a mesh structure below. To use it, just create a pivot entity in your scene and attached the script to it. When running the app, you should see something like this:
Yes, not very impressive, I know - but we have to start somewhere. Unfortunately, Leadwerks scripts currently can't run in the editor, and there is no way to render a scene in wireframe mode outside the editor when using Lua (there is an unoffical C++ call for this, though), so we have to hope the triangles are all nicely aligned...
EDIT: With shadmars wireframe material it is actually possible to visualize the triangle structure (thanks!). Looking good so far:
There are a couple of issues with this code, among them
- the automatically calculated axis-aligned bounding boxes (AABB) don't know about the shader displacement later on, so I will have to manually correct them
- at the boundary between two levels there are lots of T junctions, where a vertex of the lower level lies on an edge (and not a vertex) of the next higher level. This will generate cracks in the surface once we displace the heights. I plan to solve this in the tessellation control stage (hope it works, just an idea up to now...)
What's next?
In the next post I'll use a shader to do the vertex displacement. This is actually something like a one-liner, so I'll use the remaining space to describe some of the things about shaders that I think I have understood.
Oh, by the way: I took the entry picture to this post last week while cross-country skiing in the Alps on the German-Austrian border (I'm rubbish at it, but what the heck!). Just to give an idea what I'm aiming for - isn't nature just beautiful! I'll probably also create a dataset for that region as well, now that I have some reference images... Oh, and at the end of the month I'm going on a biking trip to Mallorca, my "test terrain", hopefully I'll be able to take some nice images there, too.
- 6
4 Comments
Recommended Comments