Spherical LOD CPU-Bound

So I’ve implemented a 4-patch LOD system similar to a quadtree. Imagine the cube faces pictured in my earlier entry, and then as you got closer to the face, it split into 4 smaller faces of equal size. The texture, height and normal maps all generated at split-time using only the position in space and some planet-based noise parameters. The output is reasonable quality (there are some annoying artefacts in the noise system), even if there are no textures (just a basic color gradient) and lousy per-pixel lighting (black artefacts everywhere). Increasing detail could be generated at increasing detail up to around 24 levels, where more detail no longer offered any visual improvement. The drawback however, is generating a 33x33 vertex patch derived from noise functions, then generating the 512x512 texture utilising 3d noise, then the normal map from that texture, is very very CPU expensive. UI stalls of up to a second per patch being generated were not uncommon, and when subdividing into 4 children, that meant a massive stall for the user.

Threading was then looked at, since I’ve got effectively 8 cores on my machine, I set about each face doing its generation in a separate thread, and the parent face rendering it only when all the children had finished generation. This was a big improvement, very near-realtime generation (very minor 100ms or so stalls) however I hadn’t even started on seam stitching or geomorphing between LOD levels yet… It’s clearly way too slow. Another consideration which made itself apparent when generating a lot of patches in realtime was the memory consumption. I haven’t implemented any resource freeing when the patches are no longer needed, so memory keeps accumulating. Since XNA lives in a 32-bit process, the upper-limit of addressable memory I have available is 2GB, though in reality OutOfMemory exceptions are being generated at around the 1.4GB mark on the allocation statements for my vertex arrays. Clearly I need to devise a way of either re-using or releasing resources which are no longer being used and possibly generating lower-resolution textures for patches of very high-detail, since in world-space they may only cover a couple of meters. Most likely I’ll implement a time-since-last-used list of patches with a maximum count of say, 250, with old patches discarded when new patches are generated based on the last time they were drawn.

Here’s some images and a video of a particular piece of the planet, in all its raw glory. The video doesn’t show the stalls in the UI when the patches are being generated funnily enough because when the thread stalls, fraps recording could not continue. If you’re observant however you will notice the FPS in the top left jump from various numbers from time to time and that’s when the splits are occurring.

Note that this video is taken post-precision fix as detailed in my previous entry, so even that I get very close to the terrain, vertex wobbling is not present.

These 4 images are in pairs. The first two are the exact same viewpoint, one showing the color-interpolated texture generated and rendered per-pixel lit, and the other showing the normal map un-lit which is generated from the heights derived from the height map.

Jump 2009-08-18 22-12-08-05 Jump 2009-08-18 22-12-11-71

Jump 2009-08-18 22-12-18-97 Jump 2009-08-18 22-12-22-14

And the link to the video on YouTube. Also embedded for the lazy people (Like me). Best to watch in HQ full-screen or the scenes that are in Wireframe will appear very, very dark.


Note: There are lots of artefacts clearly visible such as popping when LOD levels transition, seams in the texture generation means there are black lines along the far X and Y edges of each texture, so if you're careful you can see where the patches are. Also the lighting *is* per pixel, but crap at the moment.

I’ve already implemented a GPU based texture generation which uses Simplex noise, and the performance is 100% realtime and memory consumption is much much lower as well. More on that next time ;)


Tags:
Categories: XNA

19 Comments
Actions: E-mail | Permalink | Comment RSSRSS comment feed

Comments