I am working on a terrain rendering engine and I have a few questions about rendering techniques. I am an OpenGL autodidact with only a few years of experience so please forgive me if my questions are trivial.
My engine is intended for projection on big surface for flight simulation purposes.
My main constraints are :
- avoid brutal LOD transition or any visible artifacts because something unnoticeable on a monitor will definitely draw attention on a 3 meters wide screen
- keep constant 60 fps at all cost
I don’t have constraints on legacy hardware support so I can use any OpenGL 4.5 feature if necessary.
My terrain LOD algorithm is based on CDLOD. To sum it up, it’s a quadtree based algorithm and the whole terrain is drawn using a unique geometry patch. For each node, the geometry patch can be dynamically morphed in the vertex or tesselation shader to seemlessly match it’s lower detailed neighboring nodes.
The result is just perfect, I can render massive scenery with an insane amount of triangles and without any popping artifacts.
The downside of it is having only one piece of geometry to render very different materials. A lot of examples just use aerial imagery but my engine will be based on landclass texture splatting.
To avoid branching and since the land type is sampled from a mask texture, I end up having a massive fragment shader computing all potential materials and sampling a lot of textures to finally select only one depending on this landclass mask. And of course, it also implies sending a lot of uniforms and binding a lot of textures.
I can do some optimizations like grouping the tiles that are only composed of water and draw them separately using a water-only shader but that doesn’t help with silly case like 100kmx100km terrain tile with a small lake ; the water material will be uselessly computed for all fragments
At the end, the fragment shader seems to be my bottleneck. I’m also quite sure that the uniform update and texture switches for each quadtree node has a great cost.
I’m searching for ways to improve this but I lack knowledge on rendering techniques. Do you have any suggestions on this ?
Another problem I face is the rendering of vector data. I want to render roads in my engine but given the terrain algorithm, roads can’t be cut into the geometry…
I also did not try rendering roads as separate geometry following the terrain because I was worried about intersection and z fighting
I opted for render to texture. For each new tile in a close vicinity, the roads are rendered in a texture that will be applied to my tile patch. Unfortunately the cost of binding an FBO (cycling through a batch of FBOs and attaching a new texture) for each tile seems to be too important and I end up with stutters.
Any suggestion on this ? Completely different method are of course welcomed, maybe my hope for massive realtime render to texture at 60 FPS was hopeless…
Thanks for sharing your ideas !