Planetary engine, Part VI

Published August 17, 2007
Advertisement
Rings/asteroid fields

See the previous dev journal update for reference.

I've been in vacation in France for one week, during which usual development stopped. I used a bit of that time to add a couple of chapters to the new SDD.

A few days before and a few days after my trip, I continued the work on the procedural asteroid fields. I added some dust to the rings to give them a less artifical aspect; but most of the work was actually spent into the interfaces design and the ability to render gas giants ( the last gas giant dev update was only a prototype - I suspect that many people don't realize that less than half the work is done once a prototype is done, it needs to be integrated with the actual engine and game ), the GLSL atmosphere shaders, a brand new GLSL library with helper functions, etc..

FBOs on Vista

I also spent a couple of days tracking the mysterious slowdowns under Windows Vista when rendering to a framebuffer texture. Render-to-texture is heavily used in any modern engine, so it was quite a shock to learn that the overhead was coming from Vista itself. The overhead is actually so huge that it makes render-to-texture impractical performance-wise for any modern effect. To give you an idea, simply rendering to a couple of 64x64 textures goes at 900 fps on a 8800 GTS under XP, and less than 80 fps on my 8800 GTX under Vista. Nice to have such a good ( and expensive! ) video card, to get a 1100% performance hit compared to a 8800 GTS under XP ...

I have contacted NVidia, they have acknowledged the problem and are currently investigating.

Terrain engine

In the past two weeks I've been working quite intensively on the new terrain engine ( and again, the interfaces: things that are extremely important, but that cannot be shown in screenshots ).

I completely rewrote the kernel library to handle procedural functions and noise. Before, everything was in a single source code file, with tons of macros and ifdefs in order to enable / disable tests in the code ( for example the "fast noise" that I described a few months ago in one of the dev journals ). I felt that it was time for a clean rewritting. Various noise types are now available through a CPerlinNoise class, and fractal classes implement more complex behaviors ( CFractalNoise, CMultifractalNoise, CRidgedMultifractalNoise ). Each of those classes can use a callback to a noise type ( simplex noise, improved noise, fast noise ), and has its own set of parameters. At the moment I only have functions for 3D noise, so I still need to find some time to re-implement 2D noise or 3D noise with wrapping, but those are not used very much so far in the code, so I'm not in a hurry.

Heightfield generation

In the previous version of the terrain engine, I was using the following system to generate the heightfield for each terrain chunk:
- a global heightmap is generated from the 6 cube faces of the planet. Each face is usually a 1024x1024 heightmap.
- when vertices are generated, the height is first looked up in this heightmap. When the depth level increases ( you get closer to the ground ), the resolution of this heightmap becomes insufficient. At this point, the Diamond-Square algorithm is used to generate missing heights.

The big advantage with this approach is that Diamond-Square is lightning fast.

The big disadvantage is that it tends to generate terrains that are extremely homogeneous. What that means is that, wherever you go on the planet, you see the same kind of terrain features, the same sort of hills, the same shape of mountains, etc.. Basically, it makes anything under the global heightmap level extremely repetitive and boring.

I played with a lot of tricks in order to add variety, but I only had ( at the time I wrote the old version of the terrain engine ) only half successes. The main problem is that Diamond-Square doesn't have a lot of parameters to it, except its frequency ( how sharp the terrain becomes ). So while I could vary the frequency based on planetary-latitudes/longitudes, it was never possible to generate "interesting" landscapes.

In the new terrain engine, that I've been working on in the past days, I'm working with customizable classes that can redefine the terrain functions. The one I've been experimenting the most is based on Ridged Perlin noise. The main interest with ridged perlin noise is that it generates mountains and shapes that are heterogeneous ( they don't look the same everywhere on the planet ), and mountains that look ridged. Erosion cannot be implemented on procedural planets, but ridged noise gives a pretty realistic aspect to the mountains, so while it's not perfect it's definately a major step towards a more realistic terrain.

The main disadvantage with ridged noise is its performance cost: we're talking tens, if not hundreds of times slower than Diamond-square. Fortunately, everything is relative, and it remains quite fast provided that you don't go too fast at low altitudes. Fortunately, it's not a problem, because any player that tries to go too fast at low altitudes will end up being disintegrated either by colliding with the ground or mountains, either by gameplay mechanics ( friction -> rise of temperature -> ship explodes ). At the moment, I can navigate on the planet at more than 100 fps, and it should be quite easy later to generate noise in multiple threads ( that's an operation that is easily parallelize-able ).

A pure ridged perlin noise generated landscape is already interesting to explore alone, but it's possible to go further by combining it with other functions. One of those is a standard fractal noise ( with only 3 octaves ) that gives an artibrary parameter at the planetary level. This parameter is used to change the frequency or the offset of the noise, to make it even more varied.

Another function is the infamous "terrace" effect. It acts by splitting the altitudes in "steps" and changing the shape of the terrain ( sharper or smoother ) between those altitude steps. This gives a canyoning / terrace effect that is pretty nice to see. Of course, this effect is also affected by the global parameter, so that you don't find terraces on all mountains on the planet.

All the screenshots below show a typical Earth-like planet with the functions described above. Notice how each of them show different landscapes, all on the same planet. I waste a lot of time just playing around and exploring those landscapes.

Future work

In no particular order:

- real terrain texturing ( at the moment, only one texture is used, but it's tiled over a lot )
- experimenting craters
- binding some parameters to a key, and seeing the terrain morph in real-time. It's mostly for debugging, to see how parameters affect the terrain look.
- horizontal displacements, might form cliffs and overhangs
- use diamond square for the very high frequencies

Pictures time

Click on an image to see the 1024x768 version.




























0 likes 5 comments

Comments

darkwanderer
glad to see you havent stopped working on this long, but very promising project. I await the game with great anticipation, i hope that sometime next year, or whevever the graphics engines are coming together and gameplay is being implemented, alpha and beta tests are realeased to the public, even if not networked.
August 18, 2007 09:35 AM
Gaheris
Finally you're back to the most interesting part: Terrains. :)
August 18, 2007 01:11 PM
swiftcoder
Beautiful terrain... much better than the earlier synthesis, and that was already incredible.
I also gave up diamond-square in my terrain renderer, in favour of true 3D noise (ridged-multifractal in my case). The performance doesn't seem to bad, but it is far worse than before [smile]

August 18, 2007 01:56 PM
Ysaneya
Quote:Original post by swiftcoder
Beautiful terrain... much better than the earlier synthesis, and that was already incredible.
I also gave up diamond-square in my terrain renderer, in favour of true 3D noise (ridged-multifractal in my case). The performance doesn't seem to bad, but it is far worse than before [smile]


Performance of ridged multifractal isn't so bad, except that for a planetary renderer, since you can go at a few meters above the ground, I need.. 16 octaves. Also, I don't only use a ridged multifractal, but a combination of other noises to give more variety. I think in total I must be calling the noise basis at least 30 times per vertex.
August 19, 2007 06:53 AM
swiftcoder
Quote:Original post by Ysaneya
Quote:Original post by swiftcoder
Beautiful terrain... much better than the earlier synthesis, and that was already incredible.
I also gave up diamond-square in my terrain renderer, in favour of true 3D noise (ridged-multifractal in my case). The performance doesn't seem to bad, but it is far worse than before [smile]


Performance of ridged multifractal isn't so bad, except that for a planetary renderer, since you can go at a few meters above the ground, I need.. 16 octaves. Also, I don't only use a ridged multifractal, but a combination of other noises to give more variety. I think in total I must be calling the noise basis at least 30 times per vertex.


Ja, I never managed to get the system stable enough to refine closer than about 2km fromthe surface, so I was only using about 12 octaves in total. Ridged multifractal at for the low frequencies, and improved perlin for higher frequencies.

Which basis function did you end up using - a perlin derivative or something like simplex noise?
August 22, 2007 09:48 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement