Terrain Rendering

Started by
9 comments, last by joe1024 15 years, 8 months ago
Hi, I wanted to ask a question about Terrain Rendering: what kind of terrain LOD scheme is used in games like FarCry1 or Crysis. It looks like Geomipmapping. Click I don't think, they use any kind of streaming system like in Oblivion etc. But some levels in Crysis are very large (island level-> 4096x4096). How can I deal with large datasets (more than 2048x2048) without streaming. Wenn I use Geomipmapping it's stil a storage problem.
Advertisement
This may only solve part of your problem, but I was able to significantly reduce the amount of data I was storing for my terrain by separating the y values from the x and z values of my terrain data. I then created a single base x,z patch which I just reused for every patch of y values I had. This removed quite a bit of my data. I also reused the same set of index buffers per patch as well. I hope this helps, if you search around there are a several posts on this subject on these forums.
Okay, I can store height data seperatly. But then I need to use dynamic vertexbuffer, right? (not static buffers)
Because when I reuse the patches and i need to update the vertices.

And I wanted to know, what kind of LOD System is commonly used in games. The Screenshot above looks like Geomipmapping. But I'm not sure.


PS: Sorry for bad english
The data can be static, you just need two different vertex buffer inputs. You can then send both vertex buffers to the shader as input, one containing just the height information, and another holding the x,z data. You will also want to pass to the shader information regarding the translation of the x,z data so it will map to the correct position in your terrain. You can then output the translated and combined vector to the pixel shader. I developed most of these concepts based on the posts I have read in these forums, and I am certain you could find more detailed information in those posts.

Also, I agree the above post does look like geomipmapping with patch stitching to correct the holes formed between different levels of detail.

I hope that helps.
Storage problem ? You surely don`t try to target TNT-class cards with 266 MHz CPUs, right ?
Even 8192x8192x2 is just 128 MB of RAM. And 16384x16384 is still just 0.5GB, which isn`t that much these days when you need 3 GB of RAM to play the game and RAM sticks are cheap as never.

But, with terrain streaming, you`d actually use much less RAM, since the distant chunks (of which there is majority in scene), would be just some low LOD (i.e. instead of 512x512, you`d load just 32x32 for most distant ones). Of course, with DXT1 it`d take just 128 MB for 16384x16384.

So, go for terrain streaming. That`s the standard these days. Besides, it`s a wonderful world to dive into ;-)
I have 8800 GT and 2GB Ram and I think this is the hardware i'm targeting.

But when I create static buffers for each terrain patch, it is a storge problem, because the VRAM is stil limited.

I create system memory copy of the geometry data, for use in simple reads for collision detection etc, but for rendering I use VRAM. Is that wrong what I'm doing? I'm not really familiar with this.

@Valors
I have read some posts and I think reusing a single patch and translating it by using shader seems to be a good idea.

Thanks.

[Edited by - Hiyar on July 25, 2008 3:54:59 AM]
If you`re targeting 8800GT and 2 GB RAM, and you`re limited by VRAM, then you`re doing sth seriously wrong. Storing complete 3D Data for each terrain is a horrible idea. It`s good to have it at the begininng, so you always have sth which always works and can test it at any time, but it`s absolutely unusuable for real-world games.
So, as a next step create a base stream that shall be used for all chunks holding XZ coords and some base UV coords (depending on how you texture the terrain). Then, for each chunk, create a VB of the heightmap values (2 Bytes per coord). Inside Vertex Shader, convert heightmap value to YPOS and take X and Z value of base stream. Use some constant to define offset of current chunk and add it to your vertex position and you`re set. Shouldn`t take you more than half a day to do it, really.
no response...

can anyone explain, what can I do to reduce the number of draw primitive calls.
I do frustum culling but what can I do for the distant parts of the terrain.

[Edited by - Hiyar on August 7, 2008 6:27:19 AM]
are you using immediate mode in whatever API you are rendering your view(i.e.; glBegin()/glEnd() in OpenGL)? If so, I'd look into vertex buffers and the like, as this will allow you to generate a list of vertices (or indices to vertices), and draw the whole list with one call. This way, if you use a single vertex buffer per cell/quadtree node/whatever, then you only make as many "draw" calls as there are visible cells/whatever.

Note that in OpenGL, for example, you wouldn't render the primitives when doing this, rather call glDrawElements() and its friends on the whole, or part of the, list
I'm using Direct3D. I create a single vertex buffer for a base terrain patch 32x32. Then I use vertex shader for translation.

But my question is:
Here you can see terrain bounding boxes are different sizes. How can I implement this, this way I could reduce drawcalls.

This topic is closed to new replies.

Advertisement