A while ago I published a TerrainEngine demo which used oop classes to define a "terrainpatch" class and a "Terrain" class. I had never read the article http://www.gamasutra.com/features/20000403/turner_01.htm and compared it to my work.
One of the main drawbacks with my Engine was found in my height-dependant texturegenerator, which mapped textures to the ground using an algorithm that basically gave the impression it had been projected from above, so that surfaces which changed HEIGHT quickly looked "smeared". Vertical faces would be textured with "barcodes". ROAM won't help there - I need a better generator - any ideas?
This brings me to my point - my implementation was a good start on a ROAM implementation, the MAJOR difference being that we're "meant to" depart from using vertexbuffers (indexed or otherwise) and use a LinkedList of polygons instead - what's the hardware cost of this, and how can I disable the T/L pipeline ONLY for terrain rendering?
One thing about my old Height-based textureblender generator which I always wanted to add was the ability to override the textureblender with mapped textures of things like roads.
Does anyone think it's worth revisiting my TerrainEngine and adapting it to use ROAM? Was I better off just using Patches? Who has ideas about TerrainEngines?
Posted on 2004-06-26 03:15:07 by Homer
Hello EvilHomer2k

I found this book.

"Real-time 3D Terrain Engines Using C++ and DirectX"

by: Greg Snook

Paperback | 350 Pages | Charles River Media | USA Edition | 2003
ISBN: 1584502045

Maybe this is worth checking out ?
Posted on 2004-06-28 02:05:01 by Siekmanski
Maybe I asked the wrong question.
In theory, ROAM is worth the effort - it could be considered a scalable precull.
I wanted to hear from people who've tried it and/or those who have an opinion on it, with regards to its realtime merit.. remember, the system has limited resources, even if our data structures are capable of great things. My system used a static array of 16x16 patches of terrain, I could tell which patch of terrain you were above using just the player xz coordinate. The actual size of the Patches was arbitrary, but I chose 512x512 unit Patches.
I could then use a similar check to find which triangle the player was standing over based on the fact that my vertices are an xz grid which is heightmap-displaced in y.
My system was geared toward large-scale collision-detection, I could very cheaply and quickly isolate collision events for the terrain at the per-triangle level.

Compare that to a system where the vertexbuffers are constantly rewritten on the fly, you realize you need system vertexbuffers to do it, and that you can't realize the potential of the graphic hardware anymore, suddenly the ROAM system loses some appeal.
Posted on 2004-06-28 09:55:01 by Homer
surely you could have a hybrid.. is the reason you want to switch to roam, soley because of the bad texturing?
because you could still keep your geometry code and tecniques the same, but rather focus on a different technique for mapping the textures, maybe with some 'normal' trick or something.
Posted on 2004-06-28 18:17:39 by klumsy
When I wrote my terraindemo, I had never heard of ROAM. The terraindemo I wrote was a hybrid of several systems as it was, but mainly it was a testbed for an idea I'd read about procedurally generating terrain texture from N source textures based on terrain heights. Each Patch had a single Texture which was totally generated pixel by pixel using N source textures and interpolated height values. This meant I only used a single stage at runtime to render a shit-hot looking texture that blended seamlessly from gravel to grass to rock to snow, leaving the other 7 blend stages for special fx :)
The idea of splitting the terrain into "patches" was simply an attempt at culling chunks of terrain via a boundingbox approach - if the boundingbox is totally outside the viewfrustrum, we can neglect to draw its entire contents.
My terrain can be quite detailed and still quite large, but when something is far away from the observer, the detail is wasted - much gpu time is wasted processing and texturing triangles that are simply too far away to see.
ROAM takes the idea of a patcharray a step further.
In my demo, I preprocessed a 16x16 array of terrainpatches which were arranged like a chessboard to form a larger terrain. All the vertices were in write-only vertexbuffers, which the graphic card can use more efficiently. Each Patch's height information was sourced from a rectangular subsection of a jpg image, and the patch layout was such that the entire terrain was heightmapped by that jpg.
In my notion of ROAM, there's still some preprocessing, but much more work is done in realtime.
We don't keep the entire terrain's vertexes in buffers.
For each Frame we render, we resample the area of the heightmap jpg which surrounds our player into a SINGLE terrainpatch, and then we apply some specific optimisations to the terrainpatch's triangles (we try to merge triangles where less detail is needed, and create splits where more is needed, based on an error threshhold which is calculated from the height information). Then we draw it.
It occurred to me that with such a system, one could not calculate offscreen collisions with the terrain (eg you throw your axe, then turn to the left...)
Then it also occurred to me that we could apply the ROAM philosophy to the axe (in this example) in the same way as we did to the player (albeit with a smaller sample required), by generating the terrain immediately surrounding the moving axe. A further optimisation which occurred to me would be to take advantage of the bitmap nature of the image from which height information is sourced, and use alpha tricks to eliminate redundancy while resampling overlapping regions from frame to frame.
Posted on 2004-06-29 00:27:01 by Homer
Afternoon, EvilHomer2k

I've been looking up info on various terrain-rendering systems lately and haven't been too impressed by them yet.
Most are algos developed by academics with absolutely no regard to modern GPUs.

The fastest rendering of polygons on modern GPUs is by using either a triangle-fan or triangle-strip.

Triangle-lists are far too slow.

This means that a form of chunked LOD terrain where the terrain chunks are rendered as triangle-strips is far better than using ROAM.

I'm still doing a wee bit of research/writing and I'll write/draw up a posible system for chunked LOD soon.

The general idea is this:
Entire terrain area is subdivided into chunks (i.e. like your 16x16 array of terrainpatches).
The chunks are stored in vertex buffers (write only).
Index buffers are then created for LOD (i.e. 6 levels of detail).
Another set of index buffers are created for the "stitching" between each LOD for each chunk.
During rendering we obtain a list of which chunks are viewable and then render them (choosing the LOD index buffer depending upon their distance from the camera). Appropriate chunk "stitching" buffers are chosen accordingly.

Also note that the type of terrain rendering system required is fully dependant upon the type of game desired.
A top-down platform shooter really has no need for use of LOD at all.

Posted on 2004-06-29 09:32:20 by Scronty
My major requirement for a terrain engine is as I mentioned before, that detection of off-screen collisions with the terrain must be possible, and be accurate.
It would be highly desirable that such an engine be suitable for use in a server, where collision tests might need to be performed for N players against the terrain, so my concept of sampling the area around a moving object in realtime may not be so silly.
We'd keep the terrain at full tesselation, and dynamically simplify it at runtime, throwing the simplified mesh at a write-only vb at the last moment... would this work?
I'm looking forward to hearing your ideas on this stuff.

I dislike the idea of hard-switching between N fixed levels of density at N distances - this creates "popping effects" as geometry switches hard from one LOD to another. Dynamic LOD is an attempt to interpolate the LOD based on distance to viewpoint and viewing distance. The idea is that we generate our terrain at full tesselation, but then try to simplify the geometry which is being drawn. We look to the difference between the simplified and high-definition terrains to get an error value, which is then compared to a threshhold value. As long as the error is less than that nominated, the simplification is ok, otherwise we should create splits until our conditions are met. The threshhold error value we are comparing against is itself interpolated over the view distance, so that distant terrain becomes "less important", and can suffer a higher error since the triangles are distant.
Can you think of a better way to implement a dynamic LOD than hard-switching it?
Posted on 2004-06-30 00:52:34 by Homer