Archived

This topic is now archived and is closed to further replies.

Sfpiano

Is there a way to use geomipmng without creating a vb and ib for each level?

Recommended Posts

Since each level get less and less detailed, there are fewer triangles as you go down the line. Is there a way to not need to create a seperate everything per level, or to not have one massive vertex and index buffer? //------------------------------------------------------------------------------------------------------ The great logician Bertrand Russell once claimed that he could prove anything if given that 1+1=1. So one day, some fool asked him, "Ok. Prove that you''re the Pope." He thought for a while and proclaimed, "I am one. The Pope is one. Therefore, the Pope and I are one."

Share this post


Link to post
Share on other sites
In most cases you can use just one index array for every level of detail. Then you just adjust this index array according to the offset to the giantic vertex array. This problematic, since you have to cover the cracks now.

Share this post


Link to post
Share on other sites
But I don''t want to be changing the data of my buffers on the fly, and I don''t want a giant vertex buffer; I want everything to be calculated before rendering.

Share this post


Link to post
Share on other sites
You only need 1 vertex buffer. You can then have an index buffer for each patch and mipmap level. Make sure you keep your patches small enough so that you only have to use 16-bit indices. Trying to precompute everything may end up being very memory consuming if you have a large terrain.

Share this post


Link to post
Share on other sites
So if I have 3 levels of mipmapping, and I have 16 patches, that''s 48 index buffers, and my terrain is only 256x256 right now. For a full terrain wouldn''t I have hundreds of IB''s, and isn''t that inefficient?

Share this post


Link to post
Share on other sites
If you have regular heighfield, then there is one option:
One IB for the patch - 33x33 vertices (32x32 quads).
One static VB with X,Z,U,V for each LOD.
Now for every patch we have only one tiny VB with Y (height) coordinate per-vertex.
Render with vertex shader, set static VB to stream 0 for the appropriate LOD for that patch, set its ''height'' VB to stream 1, set the IB and render. Pass to vertex shader offset of that patch in the world space (the static VBs are in object space obviously).
That saves space, and works very good with geomipmapping and geomorphing.

Share this post


Link to post
Share on other sites
I''m sorry, I really don''t understand most of that. Are you saying to have an IB and VB per patch in addition to a VB per LOD?

Share this post


Link to post
Share on other sites
quote:
Original post by Sfpiano
I''m sorry, I really don''t understand most of that. Are you saying to have an IB and VB per patch in addition to a VB per LOD?


The only per-patch info is the tiny VB with the ''height'' values (Y). All other info is constant - one IB per terrain, and some VBs per LOD. If your terrain support max 8 LODs, then you''ll have only 8 such VBs.
LOD 0 VB is when X,Y,U,V corresponds for 1x1 patch, then LOD 1 is when that VB is for 2x2 patches square (next LOD), then 4x4 patches and so on. Geomipmapping...

Share this post


Link to post
Share on other sites
quote:
Original post by Sfpiano
So if I have 3 levels of mipmapping, and I have 16 patches, that''s 48 index buffers, and my terrain is only 256x256 right now. For a full terrain wouldn''t I have hundreds of IB''s, and isn''t that inefficient?


Sooner or later practically everthing boils down to a speed vs. memory trade off. You can keep all those index buffers for each LOD of each patch, or you could re-create them as the camera moves around. Depends on how much memory or CPU time you''re got spare..

Assuming your camera doesn''t move too fast you could just keep the current set of IBs around and update them when the camera changes and the LOD level needs to be switched.

Share this post


Link to post
Share on other sites
quote:
Original post by Zemedelec
The only per-patch info is the tiny VB with the ''height'' values (Y). All other info is constant - one IB per terrain, and some VBs per LOD. If your terrain support max 8 LODs, then you''ll have only 8 such VBs.
LOD 0 VB is when X,Y,U,V corresponds for 1x1 patch, then LOD 1 is when that VB is for 2x2 patches square (next LOD), then 4x4 patches and so on. Geomipmapping...


I don''t see how it''s possible to only have one IB for the entire terrain unless it''s this incredibly massive one, because you need to store different data per LOD. Triangle 1 in LOD 0 is different than triangle 1 in LOD 1.

Share this post


Link to post
Share on other sites
Using one VB/IB per 256x256 is too big; that''s really inefficient (and Direct3D hardware doesn''t accelerate indices greater than 65535 at the most, anyway). Try using 32x32 patches, or 64x64.

If you want several levels of detail, then look into something known as "progressive meshes" or "VIPM" (which stands for "view independent progressive mesh").

However, you typically won''t need more than a few LOD buffers; if you use 64x64 patches and have 4 LODs, then the size of each LOD (assuming simple 4x reduction) is: 64x64, 32x32, 16x16, 8x8. What many terrain systems do is gang LODs together, so you always deal with, say, 32x32 buffers, but they cover different amounts of area. If you draw a regular 32x32 triangle field, then you only need to bake an IB once (you only need one IB per tile resolution in general). However, you need a number of IBs, of course.

There is also the issue of seaming up between different LODs; this can be done using dynamically generated VBs, by extending the existing VBs, or by creating separate IB/VB pairs.

In general, though, "switching VBs" is not as expensive these days as it was before. And if you use OpenGL, the moral equivalent (switching VBOs, or re-specifying VertexPointer()) is fairly cheap, because OpenGL runs almost entirely in user space. So I suggest getting used to using lots of buffers, and getting it to work right, rather than worrying about the VB cost.

Share this post


Link to post
Share on other sites
you need exactly ONE vb for your terrain and for each level ONE vb per variant (cutout pieces for linkers to different lods). with 16x16 patches thats 1 ib for lowest lod, 15 for 2x2, 16 for 4x4, etc. resulting in (except 1x1 and 2x2) 16 ibs per level (+4 linkers per level that means 20ibs for every lod). the size of your terrain is changing nothing but the size of the single vb and if you start to use different ibs for different patches you should rethink your approach, because the only difference between patches is their offset into the vb.

also: texture coords per patch will always be the same, so store them once and not for every vertex. if you use vertex programs you could probably save a lot of memory by calculating x/z coords and texture coords on the fly.

Share this post


Link to post
Share on other sites
I would recomend using 1 VB per patch of 17*17, then generate ur IBs on the fly and discard them each frame. Use triagnle fans to calculate ur IBs, and u can come up with something that is considerably fast. That in combination with good culling and visibility determination should be fast enough for pleasing resutls

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
In the terrain engine for Black and White 2 I first created just a ''global'' set of index buffers for each LOD and each patch having a vertex buffer. The vertex buffers are generated and cached and kicked out of memory after a while that this patch hasn''t been visible for a while. We also had a set of precalced stitched borders of the patches, to solve the LOD crack problem. Then we wanted to add support for arbitrary edge splits (to get nicer geometry output) as well as optimizations for each splat layer, to save fillrate, since we sometimes have up to 12 passes of the terrain. When you do this, you can no longer share the index buffers anymore between the patches, since it would have different edge splits. Besides this, the terrain is completely dynamic in both texturing and geometry. Changing geometry or texturing info changes the tesselation of the terrain. Having around 256 patches of 64x64 in one level, with up to say 8 layers, each having their own index buffers and each having 4 different detail levels, you end up with lots of megabytes of index buffer data. So I built a system that creates the buffers on the fly and cache them. We have lots of caches everywhere, without these things would really run bad
I set a maximum cache size in terms of memory usage. With some clever tricks we noticed virtually no slowdowns as before when we had just global index buffers. Actually we got a bit of a speedup, thanks to the fillrate optimizations
We generate the VB''s at the highest LOD and just change the index data. The VB sizes are 64x64 (well, 65x65 actually) if I remember correctly. This was timed the fastest on current latest hardware.

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
In the terrain engine for Black and White 2 I first created just a ''global'' set of index buffers for each LOD and each patch having a vertex buffer....


Do you join patches at distance into bigger ones? Or you are not DIP limited?
And do you burn texture splatting into single texture per patch at distance as a LOD option?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Zemedelec
quote:
Original post by Anonymous Poster

Do you join patches at distance into bigger ones? Or you are not DIP limited?
And do you burn texture splatting into single texture per patch at distance as a LOD option?


No, no joining. That would also make the buffers too big, and decrease speed. If we would have decreased VB''s too on LOD, this might have been good though.

Yes, texture splatting is burned into a single texture per patch in the distance. So is grass and some other geometry, depending on the LOD. When you get close up you also have normalmaps and highres splats. The lowend cards will probably go for completely pre-baking the splat layers.

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
No, no joining. That would also make the buffers too big, and decrease speed. If we would have decreased VB''s too on LOD, this might have been good though.

Yes, texture splatting is burned into a single texture per patch in the distance. So is grass and some other geometry, depending on the LOD. When you get close up you also have normalmaps and highres splats. The lowend cards will probably go for completely pre-baking the splat layers.



I see.
But if you do not join patches, how much of them gets visible at one time - I saw a great viewing distances at some of yours screenshots. Don''t you get DIP limited?

Share this post


Link to post
Share on other sites