Terrain paging theory

Started by
8 comments, last by MV 20 years, 2 months ago
Hi all, My problem relates to the shared vertex in terrain paging. I want to use data patches (blocks) containing vertex/tris informations and to load them "on the fly" according to the user displacments. I dont know how to deal with the vertex shared with several neightboor patchs. What is the best way to deal with them ? The only solution I see is to duplicate them once for each patch, but I don''t like this method very much. Any ideas/articles ?
Advertisement
I have also been unable to come up with a good answer to this question. Right now, I have all that data duplicated on disk. Each patch of mine has a set maximum number of faces, so they''re all about the same size. The overhead''s not as bad as it could be, because my quadtrees only goes down 5 levels, but it still eats up disk space (One level''s terrain is about 120 MB, and I need to have 6 levels that have terrain). I''ve thought about doing a few things, like recalculating the basis vectors on load, but I''m interested in a solution to this myself.
http://www.cc.gatech.edu/gvu/people/peter.lindstrom/

There are several papers on out-of-core rendering of large terrains and models.
Are your files in text or binary ?
I dont know if it makes a difference in terms of disk consumning, but loading should be faster in binary.

For the shared vertex problem, maybe pointers should solve things : when loading a patch, I should check if neightboors patchs have already been loaded. If true, the shared vertex of the patch to load should be linked (pointer copy) to the one of the patch already loaded, else it should be created. Quit simple in theory, but in practice ?
try filemapping if you use less than 2GB data files.
As long as you don''t access data too randomly, it performs very well and is trivial to implement.
Anyway, when you try to build your own caching system above the os''s, you''re going to run into conflict, and evicting your data out of cache might even force the os to bring it into memory. Surely you wouldn''t want that to happen.
Act of War - EugenSystems/Atari
quote:Original post by MV
Hi all,

My problem relates to the shared vertex in terrain paging.
I want to use data patches (blocks) containing vertex/tris informations and to load them "on the fly" according to the user displacments.
I dont know how to deal with the vertex shared with several neightboor patchs.
What is the best way to deal with them ?
The only solution I see is to duplicate them once for each patch, but I don''t like this method very much.

Any ideas/articles ?


You''ll absolutely need to duplicate them. What are you worrying about? The memory waste is minimal, and after all terrain LOD must battle the memory issue.

How do you plan to cache blocks? For example we have octree, that is ''Updated'' at say 10Hz and each time for every existing patch, nearest LOD is found and compared to current minimal. That way the nearest patch LOD is found for the whole tree (the patch that will sooner change its LOD), and it is dispatched for streaming. 10 patches are dispatched per second in the perfect situation. If lag is found, ''Update'' is called at higher frequency.
Of course, nearest patches to change their LOD can be queued, thus producting more of them per ''Update'', but as camera moves that picture will be invalidated very soon. And will involve keeping track of tiles, which one is streamed right now, and which one is changed its evaluation, etc. We tried to keep it simple...
quote:Original post by Zemedelec


You''ll absolutely need to duplicate them. What are you worrying about?

I want to perform real time modification on terrain as well as editing. The access functions need to be completly reviewed if at a point you can have more than one vertex.
quote:
The memory waste is minimal, and after all terrain LOD must battle the memory issue.

How do you plan to cache blocks? For example we have octree, that is ''Updated'' at say 10Hz and each time for every existing patch, nearest LOD is found and compared to current minimal. That way the nearest patch LOD is found for the whole tree (the patch that will sooner change its LOD), and it is dispatched for streaming. 10 patches are dispatched per second in the perfect situation. If lag is found, ''Update'' is called at higher frequency.
Of course, nearest patches to change their LOD can be queued, thus producting more of them per ''Update'', but as camera moves that picture will be invalidated very soon. And will involve keeping track of tiles, which one is streamed right now, and which one is changed its evaluation, etc. We tried to keep it simple...


I didnt really understand all this .
What do you mean with updated, dispatched ?
Are all your patch organised within an octree, or is it only the patch structure ?
I plan to keep all the patch in a simple list, then to get for each frame the list of all patch in the scope (the 100 nearest patch for example), to load the patch that aren''t loaded yet then to perform for each patch the computation of the LOD level to apply using the screen error.

quote:Original post by MV
I want to perform real time modification on terrain as well as editing. The access functions need to be completly reviewed if at a point you can have more than one vertex.

Modifying access funcion should be easy, if the engine is engineered correctly. Besides - if you CUT the terrain in parts it is impossible to render different pieces and not sharing vertices - you know that...?

quote:I didnt really understand all this .
What do you mean with updated, dispatched ?
Are all your patch organised within an octree, or is it only the patch structure ?
I plan to keep all the patch in a simple list, then to get for each frame the list of all patch in the scope (the 100 nearest patch for example), to load the patch that aren''t loaded yet then to perform for each patch the computation of the LOD level to apply using the screen error.


I use geomipmapping, so every single patch on screen can vanish and be replaced with bigger one and can be split into 4 new ones. So, there is distances at which that happens for every patch. I pick the smallest distance (nearest change to happen) and preload it. Then next one, that is closer. That way when camera moves all that is needed to change its LOD (patches get replaced by other ones) is already in memory.
quote:
Modifying access funcion should be easy, if the engine is engineered correctly


Not so easy actually ; there''s a big difference between a function returning a single value and another returning several values... I would like to avoid using a vector object for that

quote:. Besides - if you CUT the terrain in parts it is impossible to render different pieces and not sharing vertices - you know that...?

Why not ? Using pointers should make this possible ; but this is not easy, I would have to maintain simultaneaous vertex and tri streams.

quote:
I use geomipmapping, so every single patch on screen can vanish and be replaced with bigger one and can be split into 4 new ones. So, there is distances at which that happens for every patch. I pick the smallest distance (nearest change to happen) and preload it. Then next one, that is closer. That way when camera moves all that is needed to change its LOD (patches get replaced by other ones) is already in memory.


Ok for this, what I didn''t understand was the 10Hz thing.
Is this the update test frequency ? I plan to do it at each frame...

quote:Original post by MV
Why not ? Using pointers should make this possible ; but this is not easy, I would have to maintain simultaneaous vertex and tri streams.

I think you want to design something in a wrong way. For example, I would do it that way (if modifications are in user-time, i.e. explosion holes and such, but not animated terrain) - modify a heightfield, and build appropriate vertex buffers from it. Modify single piece of memory, then run the good old procedure that builds VBs from heightfield.

quote:Ok for this, what I didn''t understand was the 10Hz thing.
Is this the update test frequency ? I plan to do it at each frame...

The Update() is run only at 10Hz, to save time. It just calculates LODs and predict what patches to precache. If not the precache thing, I would run it when camera moves at given delta distance... But every frame - is that needed? I mean, if camera moves relatively slowly, LODs will change very slowly.

This topic is closed to new replies.

Advertisement