   Best Method for Vast Terrain in XNA?
  I've tried various methods, and I'm not really sure which is the way to go so I was wondering what other people thought.When I say vast, I'm thinking specifically games like Oblivion and Fallout 3. I've can't seem to find a great deal of information about the tech behind the Gamebryo engine anywhere on the web.Terrain methods I've tried and some comments from my experiences:- Quadtree with Vertex/Indexbuffer per node - Seems very memory intensive for large terrains, perhaps a streaming solution could fix this?- Instanced grids, with Vertex Texture Fetch - Due to needing to use shader instancing on the Xbox 360, this suffers from high memory usage too, but lower as no need for z, therefore can use shorts.- Geometry clipmaps with CPU updates - Low memory usage, but large CPU usage and high chance of pipeline stalls, would rather use the CPU for something else.- Geometry clipmaps with GPU updates - Due to needing to use RenderTargetUsage.PreserveContents Xbox performance is not optimal, also current implementation something crashes on 360.So, what kinds of other solutions are there? What would people recommend?Also, what other methods are there for storing terrain data other than a heightmap, are there more optimal formats that would let me store larger terrains?   
  For my 4096x4096 I use chunked lod using one vertex buffer which contains x/z values only. I then transform and scale the grid and get height values from a 16 bit vertex texture in the vertex shader. One index buffer, one 32x32 vertex buffer and 32mb of vertex texture data is pretty much all you need for stitched, geomorphed terrain (I do stitching and geomorphing in the vertex shader).Nothing really new but it's relatively simple and gives great results if you tinker with the geomorphing params until it looks right.Hope that helps   ;  I once used a "streaming" quad-tree solution. The quadtree itself was like it would be completely in memory, but the underlying array class (which accepted 64bit indices, that is, on my old 32bit box) did the on-demand loading and caching. The array class was based on Linux-mmap's, but I hear Windows has something similar to memory maps in the meanwhile. Anyways, that method is rather brute-force, and I ended up with 30GiB quadtrees (for 32768x32768 heightmaps), and I created an extra JFS partition for just those quadtrees (and ended up with millions of files for each quadtree node as for my lazy ass).Here's the news-article.;Quote:Original post by phresnelThe array class was based on Linux-mmap's, but I hear Windows has something similar to memory maps in the meanwhile.Yep, a cutting edge feature introduced as recently as 1993.(sorry, couldn't resist :D);Quote:Original post by RobMaddisonFor my 4096x4096 I use chunked lod using one vertex buffer which contains x/z values only. I then transform and scale the grid and get height values from a 16 bit vertex texture in the vertex shader. One index buffer, one 32x32 vertex buffer and 32mb of vertex texture data is pretty much all you need for stitched, geomorphed terrain (I do stitching and geomorphing in the vertex shader).Nothing really new but it's relatively simple and gives great results if you tinker with the geomorphing params until it looks right.Hope that helpsHow do you pass the height/scaling values to the shader? Are you using instancing? Or a mass of draw calls?;Quote:How do you pass the height/scaling values to the shader? Are you using instancing? Or a mass of draw calls?No I don't use any instancing, I just use a 4096x4096 16bit vertex texture and use that in the vertex shader to get the heights.  Just use shader variables for the translation/scaling (or a matrix) and convert the x/z positions in the vertex shader, then using those new positions you can do a lookup in the vertex texture to find the height at that sample.  So each terrain 'patch' is a separate DIP call.  I think this could be relatively easily modified to use instancing but I haven't got round to that yet, reserved as a possible optimisation if needed.Using a distance-based error algorithm, I iterate through the quad-tree and either draw a patch or split it further based on the error metric and a few "magic number" parameters.  Geomorphing adds a little complication in that you need to calculate the inverse error metric, i.e. for a given patch, what is the distance you need to be from it in order to a) show lowest level and b) show highest level and just interpolate between them.  All that is also done in the vertex shader.  With a bit of value and parameter tweaking, you can get results that you'd be hard-pushed to beat with any other method in my opinion.  This is all assuming 4096x4096 static terrain is enough for your application (You could explore 8192x8192 which I think might be possible but then you lose a lot of bandwith for things like texturing/blendmaps, etc).For lower spec hardware, you can also just switch geomorphing off or just decrease/increase the error metric threshold depending on the visual quality you require.It's all based on pretty standard stuff, just with a few tweaks here and there.   ;  All of the above is what I assumed you were doing.The problem with DIP calls is that they are very expensive on the Xbox, well, all DrawPrimitive calls seem to be. So I would have to implement an instancing solution, but that isn't hard, it's just a shame the Xbox doesn't support regular hardware instancing. Guess I'll look into vfetch instancing rather than SM2.0-style shader instancing.Screen-space error calculation (you didn't use the term, but I assume that is your "error metric" part) is something I've not tried yet with any of my methods, so that is definately something to look into.Geomorphing I've done with clipmaps, and with the right "magic numbers" you don't notice it, and it will defeinately be going into the final solution I come up with.Plenty to think about here.I'm looking at either a 4096x4096 heightmap, or two 2048x2048 heightmaps to give the amount of detail and overall effect I'm after.   ;  How would you do your terrain texturing if you're using instancing?  When I initially did the loose design for my terrain, I knew that I wanted a good level flexibility in terrain texturing, i.e. at least 4 or 5 layers per chunk, and probably more like 8+.  I'm not sure how you'd do with this with instancing.  I'd be interesting in hearing your thoughts on that.Also, what is 'expensive' regarding the number of DIP calls on xbox360?  Do you know how many a AAA rated game uses in a typical scene?  (that's not a rhetorical question by the way, I'd be interested in knowing that figure myself being that I'm ultimately aiming for xbox360).   ;  I'm a big fan of MegaTextures and have used them in PC development before, but I'm not sure that's the best solution for the Xbox, in fact I'm certain that it's not.Alternatively you could use a texture atlas (I think that's the term?) with the RGBA channels representing your texture weights, or more than one if you need it, although this only gives you 4 textures for the whole map (8 if you use 2 "atlases"). Although saying this you can only have 16 texture samplers in a SM3.0 shader anyway, and for drawing the ground I can't imagine you'd need much more than 8, considering details such as rocks, roads, etc can be added with models.Both of these can use the same texture coordinates used for you heightmap lookup in your instances.They're pretty basic methods though, I've not given the texturing much thought yet.EDIT: I think I've nailed down some details on scale, I'm going for a 16kmx16km world, which with a 2048x2048 heightmap gives me a little under 8 metres per pixel, which I think could work if it's textured well and has enough vegitation/rocks/other details spread over it.EDIT2: Just in case anyone sees this and thinks that 16kmx16km is far too much for me to be working on, I'd like to just point out these are the capabilities I'd be aiming for with what I'm building, my intention is to use it for something much smaller and achievable, but if I want to design it with the ability to expand in mind.   ;Quote:Alternatively you could use a texture atlas (I think that's the term?) with the RGBA channels representing your texture weights, or more than one if you need it, although this only gives you 4 textures for the whole map (8 if you use 2 "atlases"). Although saying this you can only have 16 texture samplers in a SM3.0 shader anyway, and for drawing the ground I can't imagine you'd need much more than 8, considering details such as rocks, roads, etc can be added with models.I doubt you'll have much luck with texture atlases using DirectX9, so I'd advise against trying.  I spent some time prototyping using them and no matter how much I tried, I couldn't get decent results with regards to texture bleeding.  I did eventually get rid of the bleeding but by doing that I introduced other issues.  If you need to introduce any supporting textures like normal or bump maps, you're in for a rough ride I think.   