Outerra forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

Outerra Tech Demo download. Help with graphics driver issues

Author Topic: Terrain rendering techniques  (Read 27456 times)

Vylsain

  • Newbie
  • Posts: 3
Terrain rendering techniques
« on: June 15, 2016, 12:41:58 pm »

Hi everyone

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 so my main constraints are :
 1) avoid brutal LOD transition or any visible artifacts because something unnoticeable on a monitor will definitely draw attention on a 3 meters wide screen
 2) keep constant 60 fps at all cost
I don't have constraints on legacy hardware support so I can use any modern 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 !

Sylvain
Logged

cameni

  • Brano Kemen
  • Outerra Administrator
  • Hero Member
  • *****
  • Posts: 6721
  • No sense of urgency.
    • outerra.com
Re: Terrain rendering techniques
« Reply #1 on: June 19, 2016, 01:06:32 pm »

We are doing quite a bit of rendering to textures for new tiles that need to be created. Binding FBO is not cheap, but it's not such a problem that it would cause stutters. But we limit the number of tiles created per frame, and until the detailed tiles are available the renderer uses coarser parent tiles.

Couldn't you do some tricks with stencil to render different materials in multiple passes? Can omit them altogether if you know a tile doesn't contain water at all etc.
Logged

Vylsain

  • Newbie
  • Posts: 3
Re: Terrain rendering techniques
« Reply #2 on: June 20, 2016, 01:34:48 pm »

Hi cameni,

First, let me congratulate you and all people involved in Outerra project for your outstanding engine and its huge contribution to terrain rendering techniques.

About FBOs, a cause for my stutters was that I was not properly using it. I had a few FBOs and I was switching color attachment to avoid reallocating the depthstencil but this is clearly a bad idea.
I did a few tests with a pool of n preallocated FBOs, n being the maximum number of tiles using RTT at a given time, and the results are showing an improvement.
On the other hand, I quickly fill the VRAM with this technique with depthstencil buffer used only once.
Do you have any tips on this ? Maybe there's a technique between those two ? (like having a smaller pool of FBOs and copying the color texture ?)

I read on another topic one of your sentences : "The roads are defined as vector data, and they are applied on the terrain on GPU using a blending shader that merges it with the existing terrain, to seamlessly blend it in there".
I'm not sure to understand, do you draw your roads as a post process ? Or is it a render to texture of vector data at runtime, the resulting texture being used as a layer when rendering the terrain tile ?

About the multiple materials, I've always been afraid of doing multiple passes because of the amount of geometry... It's the same with the creation of reflection, refraction or shadow maps. I'm still impressed with the amount of triangles I can render with CDLOD and tesselation so I guess I'm always wrongly feeling I'm about to hit hardware limitations.
But you're right, I guess a good first step would be to separate water rendering from the rest, using stencil buffer to avoid unnecessary computations.
Can you confirm your water rendering is done the same way your terrain is rendered, ie regular mesh with all shoreline and gradient informations passed as textures.
And are those textures rendered at runtime from vector data or already as images in your data format ?

As a last question, do you have any tips on how to group several tiles in a single drawcall ?
At the moment, I have a single tile per drawcall because all uniforms (uv offset, position offset, etc...), textures (height map, normal map, landclass maps, etc...) are different.
When drawing several hundred tiles, the cost of these uniforms and texture switch is heavy and I feel like this would be a good path of performance improvement.

Thanks again for your precious advice.
Logged

cameni

  • Brano Kemen
  • Outerra Administrator
  • Hero Member
  • *****
  • Posts: 6721
  • No sense of urgency.
    • outerra.com
Re: Terrain rendering techniques
« Reply #3 on: June 21, 2016, 07:07:23 am »

We rarely use FBO with depthstencil, rather relying on the texture_barrier for programmable blending. Also, stages of the pipeline are using the same working textures, only the last one is taken from cache and associated with a tile for its lifetime.

Quote
I read on another topic one of your sentences : "The roads are defined as vector data, and they are applied on the terrain on GPU using a blending shader that merges it with the existing terrain, to seamlessly blend it in there".
I'm not sure to understand, do you draw your roads as a post process ? Or is it a render to texture of vector data at runtime, the resulting texture being used as a layer when rendering the terrain tile ?

It's a render to texture with auxiliary data, that is used by the terrain shaders or to create other cached layers for tiles.

Quote
Can you confirm your water rendering is done the same way your terrain is rendered, ie regular mesh with all shoreline and gradient informations passed as textures.
And are those textures rendered at runtime from vector data or already as images in your data format ?

It is the same mesh (data) used for the terrain, which is reused by the water shaders. The gradient data are first computed (and cached), and then used by water shaders as well. Most of the stuff is computed at runtime and persisted, that gives us some extra flexibility and we can save memory by packing it into an optimized format, but it requires extra management.

Quote
As a last question, do you have any tips on how to group several tiles in a single drawcall ?
At the moment, I have a single tile per drawcall because all uniforms (uv offset, position offset, etc...), textures (height map, normal map, landclass maps, etc...) are different.
When drawing several hundred tiles, the cost of these uniforms and texture switch is heavy and I feel like this would be a good path of performance improvement.

Texture arrays for tiles, uniform buffers or texture buffers for other data, and all can be basically rendered in one draw call in our case, with instance id used in lookups. Not sure how it would work with CLOD though.

I recently started thinking about a CLOD-like technique for stuff like clouds and water, that would be given a map texture with ids for secondary lookups for things like gradients and distance to shore. I didn't progress with it much yet, as always there are some ups and downs ...
Logged

Vylsain

  • Newbie
  • Posts: 3
Re: Terrain rendering techniques
« Reply #4 on: July 07, 2016, 12:06:49 pm »

Hi cameni.

Sorry for responding late, I've been reading a few papers about terrain rendering to have a better understanding of the subject and your proposals.

If I understand correctly, you manage to pack all your selected tiles maps into texture arrays, runtime generated maps included. And you manage to do this by packing and compressing the result of your render to texture operations without too much impact on the rendering thread.
This is quite impressive, especially when I think about the amount of textures it represents (256x256 maps on 12 levels for road maps for example) and the fact that RTT can't be done asynchronously.

Do you know any papers or articles talking about such pipeline (runtime generated resources and compression without stalling the main rendering thread) ?

This is especially interesting since I will be facing the same kind of issues for landclass shader.
I implemented array textures for my landclass data and realized texture switch is not my main bottleneck, but texel rate is.
My terrain shader samples too many textures for splatting purposes.
I've been reading articles about Virtual Textures as a way to solve this problem and since I plan to display the whole world, I can't afford a pre generated virtual texture.
I will have to compute the most detailed virtual texture pages at runtime and will have to pack it into an optimized format for a great amount of textures.

I know Battlefield and FarCry engines rely on such techniques but can't find how people handle that particular step of efficiently baking details into virtual texture at runtime.

Thank you very much again.
« Last Edit: July 07, 2016, 12:16:20 pm by Vylsain »
Logged

cameni

  • Brano Kemen
  • Outerra Administrator
  • Hero Member
  • *****
  • Posts: 6721
  • No sense of urgency.
    • outerra.com
Re: Terrain rendering techniques
« Reply #5 on: July 08, 2016, 03:30:53 am »

I fail to see where the problem is. Even non-asynchronous RTT is ok to use as a part of the rendering process. I mean, we use RTT for many tasks, preparing intermediate data for cloud rendering or lots of other stuff.

This looks like the problem is in the amount of data you'd need to render at run time, or in the excessive sampling?
Logged

Jagerbomber

  • Hero Member
  • *****
  • Posts: 1564
Re: Terrain rendering techniques
« Reply #6 on: September 16, 2018, 12:27:37 am »

https://twitter.com/greje656/status/1040933692397559810

Whoops, forgot Twitter doesn't embed here.

And still no delete post button?...  :o
Logged
"Perhaps this speaks to some larger trend within society today...  A prevailing desire on the part of indie developers to recreate the entire world into one where you can charge more than $15 for your game design degree coursework." - Yahtzee ;) :P

Jagerbomber

  • Hero Member
  • *****
  • Posts: 1564
Re: Terrain rendering techniques
« Reply #7 on: November 29, 2018, 02:11:46 pm »

Logged
"Perhaps this speaks to some larger trend within society today...  A prevailing desire on the part of indie developers to recreate the entire world into one where you can charge more than $15 for your game design degree coursework." - Yahtzee ;) :P