• Advertisement
Sign in to follow this  

GPU centric terrain rendering

This topic is 4226 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm working on the terrain-engine of my game-engine and i can't really decide what to use. At first i thought about using ROAM as i have done before, but i read about a GPU centric approach where terrain geometry is stored as small (17*17) blocks of triangle strips on the GPU. A terrain data set of 257*257 vertices would take 700 KB of GPU memory. And it supposedly outperforms roam by a factor of 2, while having a load time of 0.01% on the GPU where roam would take 10-20% percent load time on the cpu. What do you think about this approach, has anybody actually done this? Pro and Cons? Are there some more technical articles about this method? Greetings.

Share this post


Link to post
Share on other sites
Advertisement
A 257x257 grid is only 131,072 triangles. Modern hardware can spit that out with very little problem. Break that up into nicely culled patches (17x17 = 512 tris per batch) and you have a very fast system.

Personally I would use bigger patches...33x33 = 2048 tris per batch or 65x65 = 8096 tris per batch to use the vertex buffer optimally.

edit: Don't get me wrong, LOD is still usefull for very high polycount terrains, or if you have a low budget for your terrain. But if you just want to throw a bumpy grid at the screen, just do it.

edit2: spelling, grammar.

Share this post


Link to post
Share on other sites
Thanks for the responses...

Quote:
Original post by WarAmp
Personally I would use bigger patches...33x33 = 2048 tris per batch or 65x65 = 8096 tris per batch to use the vertex buffer optimally.

That's a good idea.

Quote:

edit: Don't get me wrong, LOD is still usefull for very high polycount terrains, or if you have a low budget for your terrain. But if you just want to throw a bumpy grid at the screen, just do it.


I don't get what you mean by low budget? Do you think the quality will be lower with this technique than with f.i. ROAM?


I read the article about geometry clipmaps, i was definitly going for LOD anyway, since i don't want artefacts and flickering in the background. However i thought about chunked LOD, which wouldn't really allow for that many lods as in nested grids.

What do you think about this technique quality wise? I just want the best algorithm for my engine :)


Share this post


Link to post
Share on other sites
By "low budget" he means you are limited to a small number of polygons.

I prefer chunked LOD over geomipmapping for rendering large terrains. As the rendering distance (r) increases, the number of draw calls for geomipmapping is O(r2), but only O(log r) for chunked LOD. I'm skeptical of geo-clipmaps because it requires dynamic buffers (but I haven't tried it and other like it).

Share this post


Link to post
Share on other sites
While I'm not clear on all the terminology, here is my view: If you have a bounded world, that is its not infinte, or extremely large, just render one giant mesh brute force out to horizon (with or without clipping)...this is what i do in my own engine.

If you have a very large world, break the terrain to small grid sections as described above, and have one large low-poly terrain rendered beyond the nearest cells.. I think Oblivion solved this in the best way currently.

Also, there is no reason your terrain has to be a perfect grid, as I imagine future terrain being just arbitrary meshes like everything else.

Share this post


Link to post
Share on other sites
Quote:
Original post by Matt Aufderheide
While I'm not clear on all the terminology, here is my view: If you have a bounded world, that is its not infinte, or extremely large, just render one giant mesh brute force out to horizon (with or without clipping)...this is what i do in my own engine.


Indeed!
With precomputation you can get a decimated TIN which looks indistinguishable from the original mesh with perhaps as little as 5% of the original vertices (this of course depends on the method of decimation and the terrain itself). The key point here is that all of these real-time LOD schemes really do a very bad job at approximating the terrain at the lower details, they sacrificed quality for simplicity. So if you use geoclipmaps or ROAM or whatever and render X triangles per frame, you'd probably be able to render the scene without LOD at a much higher quality while still only drawing X triangles (because you're simply doing a better job at decimating the terrain since you can do it offline).

So, for the vast majority of games (i.e. when you're not modelling an entire planet or something) you're going to get far better performance *and* quality by just pre-generating a really optimized and good looking terrain mesh (which can even have overhangs!) and rendering it brute force without any LOD at all.

Share this post


Link to post
Share on other sites
there is a GPU centric approach to terrain rendering in the book ShaderX3, although the focus of the article is more on the fact that it can be done, rather than terrain rendering itself (IMO). Not too sure if there are more resources online about it though :-/ (cos I'd be interested, myself)

Share this post


Link to post
Share on other sites
Quote:
Original post by sebastiansylvan
So, for the vast majority of games (i.e. when you're not modelling an entire planet or something) you're going to get far better performance *and* quality by just pre-generating a really optimized and good looking terrain mesh (which can even have overhangs!) and rendering it brute force without any LOD at all.


I have been thinking about that, but don't you get problems with flickering in the distance because there are multiple traingles per pixel?

Share this post


Link to post
Share on other sites
Quote:
Original post by Limitz
I have been thinking about that, but don't you get problems with flickering in the distance because there are multiple traingles per pixel?
Are you sure the flickering isn`t caused by Z-fighting due to Near/Far plane of the frustum ?

Quote:
Original post by sebastiansylvan
So, for the vast majority of games (i.e. when you're not modelling an entire planet or something) you're going to get far better performance *and* quality by just pre-generating a really optimized and good looking terrain mesh (which can even have overhangs!) and rendering it brute force without any LOD at all.
But you can have overhangs even with heightmaps through vertex shaders. Just try to look at it from different standpoint and the idea suddenly comes up ;-)
Though, editing it is possible only through your in-game editor (pulling vertices to form overhangs - but that`s still better than trying to match the texturing of the overhang mesh with your terrain in a classic method).

EDIT: Typos

Share this post


Link to post
Share on other sites
Quote:
flickering in the distance because there are multiple traingles per pixel?


I never had such a problem...I dont see how it could happen anyway, becasue at that distance everything is going to be so blurred that who would notice some flicker, if its even possible... Anyway, I'm not sure it is possible, because draw order within a mesh is pretty strictly enforced in hardware.

Share this post


Link to post
Share on other sites
Quote:
Original post by Matt Aufderheide
I never had such a problem...I dont see how it could happen anyway, becasue at that distance everything is going to be so blurred that who would notice some flicker, if its even possible... Anyway, I'm not sure it is possible, because draw order within a mesh is pretty strictly enforced in hardware.
Well, there can be pretty nasty Z-Buffer artifacts with larger terrains and a non-ideal Projection Matrix settings. If you can just easily move the front plane further (to increase precision), great for you. But there are situations when this is not possible, or results in other artifacts in a rendering pipeline.

Share this post


Link to post
Share on other sites
Quote:

So, for the vast majority of games (i.e. when you're not modelling an entire planet or something) you're going to get far better performance *and* quality by just pre-generating a really optimized and good looking terrain mesh (which can even have overhangs!) and rendering it brute force without any LOD at all.


I used to think the same thing, but truth be told, the best solution is actually a hybrid.

If you're at the point that the refined terrain mesh doesn't contain enough vertices to warrent LOD, then you've failed at keeping your vertex push high enough, and you need more tris. (Yes, Carmack is wrong on this one as well..)You should WANT LOD, because it means your mesh has enough detail in it (even after refinement) that you're getting close to sub-pixel tris in the distance of your scene. Plus, if you just rely on refeinement, that means you're blowing cycle time in the distance, rendering those high detail sections, which are all getting mapped to small pixel output (bad for perf!!) What you really, (and trust me, i mean REALLY) want to do, is refine your mesh like normal, but refine out your higher detail sections into a second data set, that you can 'dial in' based upon visible distance to the area in question. This way, you get constant refinement in the distance, and you get your detail up close, both without having to blow too many CPU cycles, or to much memory overhead.

~Main

Share this post


Link to post
Share on other sites
Hi,

I am definitly going for LOD and i will not be needing overhangs anyway:). After all your post i think i'll have a go at it now, see how it works out. I am going for chunked LOD with 6 levels (1<=level<=6) from 3*3 to 65*65. I will create these blocks by storing 3 triangle strips on the GPU per level (except for 3*3). (see image) The first strip (grey) is the inner grid of size (2^level-1)^2. The blue and the green strip are the same strips (rotated) and connect the block to another block of the same level. The red and the yellow strips connect the block to a block of level-1 (and are the same to). I will fill the vertex buffer so that by simply adding setting an offset the interconnection strips will "rotate", (i will store it like grey @ red @ green @ blue (right to left @ yellow (bottom to top) and the level to level-1 strips will simply skip some vertices).

a 9*9 grid


I will use a simple distance vs detail algorithm to decide the levels for the blocks, while making sure that the difference in level from adjacent blocks does not exceed 1.

I believe i have best of both worlds, using LOD while still using the power of the GPU to output a trianglestrip fast.

Does someone think i am making a mistake, doing it like this?


EDIT:
I am actually going to add another strip, the blue one flipped over y for top and bottom (to avoid zigzagging)


Thanks for your posts so far.
Greetings.

[Edited by - Limitz on July 28, 2006 12:11:58 PM]

Share this post


Link to post
Share on other sites
Quote:
]Original post by Limitz
I am definitly going for LOD and i will not be needing overhangs anyway:). After all your post i think i'll have a go at it now, see how it works out. I am going for chunked LOD with 6 levels (1<=level<=6) from 3*3 to 65*65.

You don't seem to understand the chunked LOD algorithm. In chunked LOD (typically, but it's not required), every LOD has the same number of vertices; however, the LOD covers the same area as 4 of the next higher resolution LODs.

The algorithm you are describing is similar to geomipmapping. In geomipmapping, the next lower resolution patch has every other row and column of vertexes removed.

Your crack removal scheme is not very efficient. It requires 4 extra draw calls per patch. There are two ways you can improve it. If you restrict the difference between adjacent patches to 1 LOD, you can precompute 16 versions of each patch level and select the proper one to draw. Also, you can remove the extra vertices in the higher resolution LOD by modifying the index buffer.

Share this post


Link to post
Share on other sites
Quote:
Original post by JohnBolton
Your crack removal scheme is not very efficient. It requires 4 extra draw calls per patch. There are two ways you can improve it. If you restrict the difference between adjacent patches to 1 LOD, you can precompute 16 versions of each patch level and select the proper one to draw. Also, you can remove the extra vertices in the higher resolution LOD by modifying the index buffer.


Yes, i thought about precalculating 16*6 maps, the thought about having to much overhead held me back, however it may be the best solution after all. I tried my first solution and i quickly ran into some problems. I eventually thought this up to minimize overhead. 4 triangle strips per patch



I think i may go for some overhead after all, and precalculate all the combinations of patches.

Thanks for the advice.
Greetings

Share this post


Link to post
Share on other sites
Quote:
Original post by Limitz
Quote:
Original post by JohnBolton
Your crack removal scheme is not very efficient. It requires 4 extra draw calls per patch. There are two ways you can improve it. If you restrict the difference between adjacent patches to 1 LOD, you can precompute 16 versions of each patch level and select the proper one to draw. Also, you can remove the extra vertices in the higher resolution LOD by modifying the index buffer.
Yes, i thought about precalculating 16*6 maps, the thought about having to much overhead held me back, however it may be the best solution after all. I tried my first solution and i quickly ran into some problems. I eventually thought this up to minimize overhead. 4 triangle strips per patch
...
I think i may go for some overhead after all, and precalculate all the combinations of patches.

You can also do "skirts". Include a strip around the edge of each patch that hangs down and fills any cracks. It could be part of the patch geometry so that each patch requires only 1 draw call. It is not an elegant solution, but it works well and it is very efficient.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement