Distant Terrain Rendering

Started by
23 comments, last by EvilDonut 15 years, 9 months ago
I have been doing a little personal project with the goal of rendering as realistic looking terrain as possible. At the moment I'm using a simple smallish heightmap and blending three different textures (grass, rock, snow) by an amount depending on the height to simulate mountains. I'm performing this blending in the pixel shader, along with detail mapping, bump mapping and simple lighting. I'm implementing fog in the vertex shader. I'm using an adaptive LOD algorithm based on computing Binary Triangle Trees of the terrain at initialisation. At each frame the tree is traversed in order to determine which level of detail is drawn, this computation uses the distance of the tree node to the viewer and the error metric computed at the beginning. After much tweaking, this seems to be working just fine. I do notice some 'vertex popping' as the distance changes to certain features, but the tweaking has minimised this effect to an acceptable level for me. I thought about interpolating between the two levels of detail in the vertex shader, but I'm not sure how to go about this yet. My main question relates to how I should go about rendering very distant terrain. I want to achieve a similar effect to Oblivion, which involves something like a 16km^2 map and you can see the mountains in the distance from very far away, whilst the detail of the immediate neighbourhood remains very high. I know this probably couldn't be achieved by a heightmap alone, as when you set the far clip plane to a value sufficient to display far terrain, your resolution/granularity is decreased to the point where you can't display fine detail at small distances. I don't know exactly how oblivion achieves the awesome distant landscape effect, but I know it involves pre-generating some LOD meshes and distributing those with their heightmaps. Does anyone know more detail on how Oblivion achieves distance landscape rendering? Also, are there any other good methods of achieving this? I've been researching this for the last couple of days but haven't been able to find any papers/web resources that describe 'exactly' what I want. I think first I need to generate a heightmap far bigger than the one I have now, as I can almost see one corner from the diagonally opposite corner at the moment. But how do I actually render it such that it will not be clipped for being too far away, without having to increase the far clip plane (as that would reduce the granularity of the depth buffer and thus the detail at close distances)? Following are 3 screenshots of my terrain renderer so far: With texturing: The same view as wireframe, to see the LOD algorithm in action: Moved slightly forward from previous position, note the slight increase in detail at the bottom of the slope at the center of the scene as the camera has moved closer to it: EDIT: Oh, During my research I did find out how oblivion handled distant objects/meshes (such as the main tall tower in the middle, for those who have played the game) - they have a separate lower-detail mesh that is rendered when the 'far view distance' option is enabled. They don't perform collision detection or anything on this mesh. I do not know how they handle distant landscape though, that is what I am interested in for now.
Advertisement
I dont know how it's done in oblivion, never played it.
But as you said, either use a terrain lod scheme which handles very large datasets well (e.g. geoCLipmapping) or render far away landscape into a cubemap which gets updated every now and then (every 20 frames or so...). Distant level geometry was done that way in shadow of the collossus (ps2).

The Making Of "Shadow Of The Colossus"

Edit: typo geomipmapping -> geoclipmapping

[Edited by - stephanh on June 24, 2008 7:53:39 AM]
Thanks for the response, the cubemap method sounds exactly the kind of thing I need. I don't think its possible to use a terrain LOD scheme to render really distant land, as the vertices for this terrain will need to be beyond the normal clipping distance (perhaps even 10 times the clipping distance or so). The only solution for that problem (that I can see) seems to be substituting a texture for the distant land, such as you suggested, and rendering that texture just inside clip range.

Since I posted my original question I found a similar previous question posted here last year, and one of the suggested solutions was to render distant landscape to the skybox which sounds quite similar to what you suggest.

I'm not sure how to actually go about this though. After doing a quick google search I came across an article indexed on IntroGameDev.com in 'Game Programming Gems 2' - the article is called 'Rendering Distant Scenery with Skyboxes', which is exactly what I want. The problem is I cannot find an online version of this article, it seems to be available only in printed form and for a price - anyone know if this is available online and free anywhere?

Does anyone know of any good online resources that will help me render distant landscape to a texture? I have quite limited experience with 3D graphics, and I have never used anything other than standard 2D textures and techniques no more complicated than detail/bump mapping and texture splatting.

At the moment I'm distributing the LOD mesh calculation over several frames, as it is just too expensive and unneccesary to perform every frame. I guess this method would probably also need to be distributed, and if so then the framework for that is already in place, which is good :)

I had a quick look at the Shadow of Colossus screenshots, and it looks like the distant terrain is clearly separate from the foreground. Whilst it still looks quite nice, whatever technique oblivion uses creates a pretty much seamless transition between foreground and distant background. They may use a texture-based approach to rendering distant land, but it seems like the main problem with that approach is the seam created between foreground and background and, if they are using that method, then they manage to solve this problem extremely well!

EDIT:
Here is a link to a screenshot showing an example of distant terrain in Oblivion: http://planetelderscrolls.gamespy.com/screenshots/?ss=919&view=ss&page=1&cat=4
Note how the mountains in the far distance on the horizon seamlessly blend with the closer terrain at the foot of the mountain, and how there is less fog applied at the foot of the mountain than towards the top, which further gives the impression of volume. If they are using a texture to render the distant land, then they are doing it pretty much seamlessly, and the texture itself really gives the impression of volume. I wonder if I can turn on wireframe mode in Oblivion which may give me some clue as to how it works. I'll try that now :)

EDIT 2:
Ok, I tried wireframe mode in oblivion and the results surprised me - they aren't using any kind of texture to show distant terrain, they are actually rendering distant landscape and stuff using a terrain lod scheme that relies on precomputed low triangle count meshes that are substituted in when the landscape is far away. More surprising was that the area of terrain immediately around the camera was shown in full detail, i.e. even when flat-ish terrain could be vastly simplified into like 100 times less triangles, it still renders each and every small triangle instead of trying to compute a low-error simplification of the immediate area. This might partially explain the bad framerates I'm getting with the game, as they could do some optimisation on the immediate area's mesh.

The problem I've been getting with actually rendering distant terrain using vertices is that to give the impression of vast scale I have to have the camera close to the surface, lower the movement speed, and apply a fine detail map to the immediate area. This means I have to have a 'near clip plane' of like 0.01f, or when I look down at my feet the terrain will disappear as it gets clipped for being too close, whilst I still need a far clip plane of like 100.0f or the distant terrain gets clipped. Having a very far far plane and a very near near plane means the granularity of the 16 bit depth buffer gets decreased and you notice Z-fighting and other problems, and I'm not sure how to get round these.

[Edited by - EvilDonut on June 23, 2008 7:33:45 AM]
The far clip plane matters surprisingly little concerning depth precision. You can even push it to infinity.
I usually keep my near plane around 1.0 - 1.5 for a human-sized observer and push the far plane as far as necessary.

Rendering such large terrain, assuming with 16km^2 you mean a ~ 16k*16k heightfield, it's more a storage problem. You are dealing with 1GB of raw float-height samples then. Data has to be paged-in on demand using a LOD-scheme supporting some kind of out-of-core rendering. Additionally it might be wise to compress that data.

Your LOD sounds like chunked-lod which should be able to handle such amounts of data (with paging).

But i doubt the terrain is that detailed in oblivion, ground clutter and close object meshes do their share do conceal nearby terrain detail. And simple fog or atmospheric effects provide a good depth impression.

How large is your current heightmap? What hardware do you target?

Yeah, the terrain LOD in Oblivion is a ridiculously simple two-level scheme--the high detail terrain is just a regular heightmap and the low-detail is highly simplified. The simplicity of it is mainly just disguised by the really fantastic work the artists did (and, as stephanh pointed out, the large amount of clutter helps to hide the transition).

I actually wanted to do a much more sophisticated scheme but time was really limited. :) I'm very excited to see how people react to Fallout 3's terrain/object LOD scheme since it's quite a bit more awesome.

I think the main point to take from Oblivion, though, is that fantastic artwork goes a long way to making something look next gen and high tech, even when (as in the case of the distant terrain) it's actually pretty simple under the hood.
Orin Tresnjak | Graphics ProgrammerBethesda Game StudiosStandard Disclaimer: My posts represent my opinions and not those of Bethesda/Zenimax, etc.
Yes, the amount of clutter in outdoor areas really masks the low terrain detail. I tried turning on noclip so I could fly to about 100 metres above the surface, then turning down the foliage/object render distance as low as I could. I was then high enough to see the neighbouring low-detail patches clearly, and they have a very low triangle count. Also, when I flew towards them so that the high detail patch was loaded the terrain would suddenly and quite significantly change, an effect which is hardly observable when at normal heights above the land due to the foliage etc.

I think the prettiness of oblivion's outdoor areas is very much related to the foliage (SpeedTree powered) and nice skybox/lighting, and if I could make a terrain renderer half as good as Oblivion then I'd consider this project a success :)

My previous heightmap was only 512x512, but I'm now attempting to use Oblivion's heightmaps instead as its a convenient source of large prebuilt height data. Oblivion uses tiled heightmaps, each of size 1024x1024, of which there are 14 for the main outdoor world. Each of these tiles appears to be further divided into 32x32 cells, each cell 32x32 pixels in the heightmap. I believe their coarsest LOD simplifies each cell into a single quad, but I may be wrong there as I've not investigated it that closely. I will be trying to combine my CLOD method with these heightmaps and see what happens.

Fallout 3 sounds interesting, are you able to give some kind of overview of the terrain LOD method being used or is that still hush hush for now? :)

stephanh: I'm developing on what is now a fairly low end machine - Athlon XP 3800+, 2GB RAM, GeForce 7600 GS. I'm getting about 45fps at the moment which is pretty poor for such a small heightmap. However, I haven't yet implemented any frustum culling stuff, and my LOD calculations consider the entire terrain, not just the terrain that is currently visible - so there are plenty of optimisations yet to make. I started this project over a year ago and am only just picking it up again. At the moment I'm spending most of my time trying to remember what the various pieces of code did, as I'm not big on commenting my own code :)

I'll try setting the near clip plane a little closer to 1.0, and increasing the far clip plane. I will then need to raise the camera off the ground and rescale the terrain to compensate for this.

Thanks for the help!
I was reading a few months ago that John Carmack for their new engine found LOD pretty much a waste of CPU cycles and that just blasting all the triangles to the card was faster anyways. You might actually want to try removing your LOD code and see if it's that much slower. I've tried doing this and ended up gaining quite a few FPS. I even had 2-3 different LOD techniques in the code I could swap between and all were slower then just rendering all the polygons which surprised me. Just depends on how your code works. Inefficient code (not saying yours is) with great LOD is still inefficient and slow. Might be an interesting test for you.

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

I had tried that a while ago, and without any LOD at all I get 60 fps (I capped it at 60 and just slept for any extra spare time), but with LOD I got 45fps - so yes, its a big speedup using no LOD at all :) But that was with 512x512=262144 vertices, and I even had to spread my LOD updates over like 20 frames. The heightmaps I'm using now consist of about 14M-verts in total, and I really don't fancy sending all that to the gfx card without any LOD, even with frustum culling. I think my code is also fairly inefficient, as it is the result of a sort of evolutionary design process and as such contains a lot of redundant code.

I think John Carmack is right to some degree, but I think there exists a tradeoff between how much effort you put into LOD and how much you just brute force. As cards get better, that tradeoff gets pushed towards the 'brute force' end of the scale, but then you eat up a large portion of your triangle count which could be better used on the various models etc in your environment. I would certainly want to at least have two levels of LOD, like Oblivion, with near terrain at maximum detail and far terrain at minimum detail.

I'm now attempting to implement geoclipmapping with the Oblivion landscape, as that seems to be fairly cutting edge and suitable for large terrains. It actually looks fairly simple too, I don't have to mess around as much with recursively subdividing triangles and maintaining loads of pointers between neighbouring triangles and ensuring that they perfectly tesselate, etc, as I was doing with my previous LOD scheme - that was a massive pain to implement.
I partly agree with Carmack. I don't think he's dealing with datasets as large as we are--when your game area is measured in miles on each side, you need SOME kind of geometry LOD, or you very quickly end up vertex-limited, not to mention filling up tons of memory with distant vertices that make little to no contribution to the scene.

I do think that continuous LOD schemes are essentially a waste of time on modern hardware. You always want to be focusing on blasting big batches to the video card. The point of LOD is to reduce (1) the number of triangles by VERY BIG amounts, since small tricount optimizations make essentially no difference in rendering time, and (2) the number of batches, if you're using some kind of hierarchical scheme. And of course (3) to reduce memory usage.

So yeah, I'm a big fan of chunked LOD and related schemes, in case it's not obvious.

(Can't really talk about Fallout LOD at this point, obviously. But try going into wireframe once the game comes out and it'll be pretty easy to see how it works. :)
Orin Tresnjak | Graphics ProgrammerBethesda Game StudiosStandard Disclaimer: My posts represent my opinions and not those of Bethesda/Zenimax, etc.
Quote:Original post by lancekt
So yeah, I'm a big fan of chunked LOD and related schemes, in case it's not obvious.


I`m extremely glad to see there are pros that still think that chunked LOD is a usable alternative (with proper tweaking).

To OP: The whole "huge terrain distances" feature is actually just a hack, an effect.
Consider the following terrain (16x16 km, 32768x32768 heightmap - i.e. 2 billion triangles). With properly chosen chunks (i.e. VB/IB pair), the framerate skyrockets to over 3000 fps (on 7950GT and 1.6 GHz CPU).


Terrain Shot 2

It`s all just an illusion and depends on how you define your terrain - i.e how it looks - if it does create the impression of huge terrain or not. The above shot shows that you can easily have an overview of 16x16 km, but if necessary, down there you can have a detail of 0.5m per vertex, just switch to proper LOD Indices/Vertices. Of course, with such amounts of data, you need to hold only 16-bit value of YPOS and calculate the rest inside shader.

VladR My 3rd person action RPG on GreenLight: http://steamcommunity.com/sharedfiles/filedetails/?id=92951596

This topic is closed to new replies.

Advertisement