Submitted by , posted on 07 April 2001

Image Description, by

Hi IOTD Watchers,

Some of you 'may' remember my IOTD from a few months ago - it was a Multi-Fractal Terrain demo rendered in sort-of-realtime using ray-casting onto an infinite, implicit surface with SIMD optimised multi-fractals :) (demo at

Well now I'm aiming at the whole planet rather than just a flat terrain. It's vanilla C & OpenGl.

With traditional terrain rendering, there is a (potentially huge) data set defining the terrain. Even with wavelet compression I doubt you'd get a small planet into a reasonable amount of memory - but it may be worth invetigating!

Another approach, taken here, is to have no stored or precalced heightfield. The surface of the planet is instead represented by an 'implicit surface', i.e a function, f, that returns the surface height given a position P. So h = f(p) :)

'f' is a multifractal function based on the work of Ken Musgrave, who's currently working on a 'commercial' fractal world called Mojo ( I build up many layers of random noise at increasing frequencies and magnitudes. For the flat terrain I used Perlin's Noise2 function within 'f' ( For this Fractal Planet i've moved to the Noise3 function which obviates the need to map a 2D function around a sphere. The Noise3 function is inherently slow (lots of lerping) so at some stage I'll implement a SIMD version (as I did for Noise2 previously) which should easily double its speed for PIII users.

The height function is also used to generate the surface texture (based on an index into a 1D surface type (colour) array - re Musgrave) This makes the texture match the terrain (varied by latitude).

The surface mesh is a simple bintree with level zero being a 8-sided diamond (Octahedron). The first screenshot (top left) shows the mesh split down to level 6 with the whole sphere tesselated down to 17000+ triangle. Each subsequent image (TL->TR->BL->BR) is a further level (or two) down. NB the terrain height has been GREATLY exaggerated to aid visualisation!

The intention is to be able to get down to ground level and still see detail. To get a 10 meter resolution mesh would require around 40 splits (based on a 6000KM radius planet) which would result in a sphere of >4 trillion triangles! I doubt a even a GeForce3 could handle this ;) So lets CULL and LOD! Currently I have two pre-Opengl culling routines: Horizon Culling and View Cone Culling. Horizon culling is done at the level 6 mesh. At altitude 'a' above the surface, the horizon is sqrt(2*a*Radius+a*a) away so I do a quick distance check for each tri and stick them in my horizon culled pot. I then split these tris down to level 12 and carry out the view-cone cull. This set is where I plan to carry out the final LOD splitting stage. It will be some sort of ROAM-esque LOD - probably with splitting based on distance and 'wedgies', with a merge queue to free up memory.

Usually, LOD systems are based on a predefined heightfield so they work bottom up - simplifying the smallest triangles upwards to larger ones based on some visual error metric. In this case I have no predefined data so I work downwards from the large tri's. A key point is that this can be tied in with the multi-fractal function - each frequency of noise contributes less and less to the overall height but represents features of smaller and smaller scale. For a point far away we may need only 2 or 3 octaves of noise. As we get closer we add more and more additional octaves to get the fine detail. We only need to split if the split pair is noticably different when rendered, so for flatish pairs we can defer a given split till we are much closer. Initially though I'll just try pure distance based splitting on the final culled triangle set. Once this is in and I've added some flight controls I'll post a demo.

Hope to release the demo soon at!


Rob James

Image of the Day Gallery



Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.