Wednesday, September 21, 2016

Colorful planets

I accomplished only a little of what I set out to do today, but I think it was fairly effective.  Terrestrial worlds now have a nice color scheme applied, based upon latitude and elevation.  A fractally-perturbed latitude value and the elevation value are used to calculate an index into a one-dimensional color map that ranges from a desert-like tan at the equator through several shades of green to a gray and white for the tallest mountains and the desolate polar regions.  You can see the resulting texture being applied to both a 3D globe and as a flat map.

A terrestrial world, in globe view

There's a flaw in the color map I used (based upon the one from Ken Musgrave's dissertation) which is that the desert-like tan colors are along the equatorial belt.  On Earth, the equatorial region is largely a lush region of vegetation, with drier regions to north and south before wetter regions are again encountered a bit further from the equator.  Musgrave mentions this in his dissertation, and I wondered why he didn't use a more Earth-like color map, but I realized as I was implementing that it would make the latitudinal and elevation contributions to the position on the color map harder to calculate.

Terrestrial world, in map view
What's left, then?  Well, a lot, actually, but most are fairly simple.  Clouds and ice caps, for example. The dimples for the craters on the rocky worlds are still missing, and should be added.  A toolbar in the GUI might be nice.  A form allowing the user control of some parameters would be nice.

In the example from his dissertation, Musgrave implemented a steeper "bump" in the color map for higher elevations. I haven't done that, but think I probably should.  Mountains in regions closer to the equator than the poles currently end up with dark green mountains; some are high enough they should really be gray or even white if tall enough.

A second terrestrial world, in globe view

A proper implementation of the DNoise algorithm, to improve the Venus-style clouded worlds, would also be nice - but that's a bit more complex.  Another idea is to add a feature for export to OBJ format to allow importing into 3D programs like Blender, POV-Ray output is another possibility.

Another somewhat-involved improvement would be to parallelize the fractal noise generation, possibly even offloading it from CPU to GPU using OpenCL. Generating fractal noise is only part of this program where the performance is poor - it can take several minutes to generate the noise for a terrestrial world at a resolution of 4096 x 2048, while turning that noise into a texture with pretty colors takes a few seconds (or less).  I want the ability to go to higher resolutions than that, so performance really needs to be improved. Generating the fractional Brownian motion (fBm) noise with Perlin noise as its basis function is definitely possible using the GPU; I experimented with it sometime in the last year or so in a stand-alone application.

That second terrestrial world again, in map view

I'm also not sure about the color scheme I'm applying to the ocean based upon depth.  I'm going to look at some more photos of Earth from space.  While the seas are somewhat lighter in shallow waters, I don't think the deepest of the deeps become noticeable darker, like in my images.

On the code structure aspect of this, I'm planning to split the planet texture generation into separate classes, with a common base class containing many of the common functions (noise generation, color mapping, etc.) and a virtual method GenerateTexture, which shall accept as arguments the width and height (in pixels), and sea level, cloud cover, and ice cover as percentages.  Crater activity may also be an argument.

No comments:

Post a Comment