Not logged in, Join Here! or Log In Below:  
News Articles Search    

Submitted by Rob James, posted on April 07, 2001

Image Description, by Rob James

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


Message Center / Reader Comments: ( To Participate in the Discussion, Join the Community )
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.

April 07, 2001, 01:13 PM

That's a neat approach!

Is it possible to make part of the terrain pre-defined and/or to place objects on the surface? That way you could have for instance a small moon (Rendered to arbitrary detail with your current algorithm) with a single enemy base on it.


Lion V

April 07, 2001, 01:45 PM


James Matthews

April 07, 2001, 03:00 PM

Perhaps I'm talking outta my ass here, but what about using IFS for terrain generation?

Take a surface map of Earth (for example, or any planet you want to represent) and transform it using the IFS algorithm. Is there anyway to then use that information in a similar way that you've described (having terrain as an implicit function).

Like I said, I've no idea what I'm talking about, just an idea...:)

Neat IOTD, by the way.


Hannu K.

April 07, 2001, 04:44 PM

Nice approach and a detailed description. Great job.

And is it already possible to go very near the ground level with increasing detail and a decent framerate? If so, I wanna see it :D

zed zeek

April 07, 2001, 05:52 PM

coincidence, i am gonna try my hand at writing a demo today where the planet hangs in space and you can zoom into the details. though im gonna uses a different approach than you rob. nice one, this means i will have to write it, fate talks :^)


April 07, 2001, 06:14 PM

nice work though colors look awful and mountains look too sharp
for me.. I was wondering if it's possible to optimize noise function
when near surface because then lowest octaves( with lower freq )
are near constant value. It will become computationally intensive
if zoomed very near surface and number of octaves keep on increasing.

I've made almost realtime perlinnoise voxel landscape and i got
dramatic drop in frame rate when zoomin near mountains due to the
increased number of noise waves.

Bruce Sutherland

April 07, 2001, 09:59 PM

Just wanted to say, it's great to see an IOTD with such a complete and in-depth discussion of the implementation. Keep up the good work!

Oscar Rydberg

April 08, 2001, 06:01 AM

Nice work, however those mountains are indeed a bit sharp for their mother planet!

If You go to NASA and look at their spaceshots of several planets, You'll notice that the earth looks like a perfect sphere until You'r somewhere in the atmosphere. Not until closer than that You'll start noticing the mountains popping up..

Try using high resolution textures and without any heightmapping until absolutely necessary (some thousand meters above sealevel),
it's amazing how far You can zoom in and still get realistic pictures.
Bumpmapping is a VERY nice technique in this case.

Good luck with Your project!

Alexander Blach

April 08, 2001, 09:00 AM

The terrain may be "too sharp".

But look what he says in his description:

"NB the terrain height has been GREATLY exaggerated to aid visualisation!"


April 08, 2001, 12:18 PM

I've been trying to do something like that, but I just can't figure out how to change the sphere, and keep all the triangles connected. My planets keep blowing up! Please, tell me how do you do it! It's driving me nuts!

Rob James

April 08, 2001, 04:00 PM

Jeroen -
Yes, you could create a user defined 'patch' on the terrain and render it using standard techniques - It's on my todo list for this demo :)

James - There's lots of work being done in the field of terrain compression. Theres some good wavelet stuff around. Ideal if you want to render an existing planet. I don't know how you'd create random planets though... (must be possible!)

Hannu - it's getting down the 100's of meters (around 28 levels down the split bintree) and the fps on my PIII 650 / Savage MX (yep - it's a laptop!) is about 6fps... But I've LOTS of optimisation to do yet :)

juhnu - The colours are just throw in at the moment! They are there as an indication that my planet texture mapping code corresponds to the height code - the use the same parameters to the noise function except # of octaves. Using PIII SIMD code even the Noise3 calls dont take a significant % of frame time. I could speed things up by storing a 'octave depth' for each vertex and only calc'ing a few octaves far away and adding to these as we get closer. Only brand new vertices produced as the results of a split would need all n-octaves calc'ing.

Bruce - Many Thanks! I have been distraced by playing Black and White but I have vowed to put that aside for a few weeks :)

Oscar - agreed, but because I want to cache Noise3 octaves along the way it actually pays to start calc'ing a few octaves from far away even though you wont see them yet. The texture mapping is a whole new area that I'm leaving until last. I want a progressing method, sort of LOD for textures, again using Noise3 and pehaps stealing a few cpu cycles each from to build up higher resolution textures depending on the viewpoint location, altitude etc...

Jesse - The actual sphere starts out as a octahedron. One interesting think I do is store the base vertex co-ordinates as ZERO ALTITUDE co-ordinates. If you rendered them you'd get a smooth sphere. The altitude is stored in the vertex structure as a seperate displacement value. This makes it simpler to generate new vertices when splitting existing triangles. But maybe you should try some 'flat' terrain rendering first of all :)

Demo soon (within a week or so!) I'll be very interested in how it performs on a newer T&L card rather than my rusting V3500!


Rob J.


Joachim Hofer

April 09, 2001, 09:02 AM

Sorry for the late posting, hope anyone reads this (and is interested :)

I am working on something similar at the moment. But I use a function
RxR -> RxRxR

Then I just write a tesselation of a 2D square, and then it is transformed into a 3D tesselation of basically anything by the function (not only a hightfield, also 90%+ cliffs are possible). And as the function can be differenciated (if this is the word) I only have to do partial differenciatiation and then cross product to get 100% correct vertex normals.

Anyways I not already implemented some good LOD for the 2D square tesselation, and so it only renders small objects so far. But I already did 3000 (different!) Asteroids, each consisting of up to 3600 Vertices. It calculates it with around 20000 Vertices per frame at 150 FPS without rendering and 40 FPS with rendering the triangles on my PIII 1GHz.

As soon as the thing is finished, I will post something on IOTD :)

I hope I didnīt bore you...


April 09, 2001, 12:13 PM

Did that( I'm trying to move on now.


April 09, 2001, 12:20 PM

Does that pnoise simd code work on Athlon and other processors having no SIMD support? Or maybe can it take an advantage of using 3DNow! ?
I think relying only on SIMD instructions is not the way to go

Rob James

April 09, 2001, 02:40 PM

I'm looking for someone to convert to 3Dnow!

Also, given that XBox is PIII then it 'could' be a way to go console wise ;)

Rob J

This thread contains 15 messages.
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.