Tuesday, September 12, 2023

Another decision point

Time (at last) for a new update!

I have, more or less, managed to convert all of my existing terrain and climate routines to work with spherical planets. This has been quite fiddly to do. Some could be converted fairly straightforwardly, while others could not. In some cases I had to rewrite them from scratch, and in extreme cases I had to simply alter them to work with a giant 2D map which subsequently gets wrapped onto the sphere. In some cases I found that the rewritten versions were better than the original - e.g. my continent-generating routines now seem to throw up more varied terrain more often, including archipelagos, meaning that I don't need to use the Aegean-creating function.

I was particularly held up by a subtle but nasty bug in my routines for moving from one point on the sphere to the next, which caused inaccuracies when moving from one face to the next. Much of my time was spent writing workarounds to deal with the effects of this bug until I finally found it, after which I had to go through and remove some of those workarounds.

But it's done! Mostly. All four of the planetary types (small continents, large continents, oceanic, and non-tectonic) can now be in spherical form, and in all three planet sizes too. Most features such as mountains, dunes, lakes, wetlands, craters, etc. are present, as are the variable climates (including exotic climates). There are still some issues. Artefacts occasionally appear at the edges of faces, and occasionally the whole thing crashes. So there's still some work to be done smoothing it all.

Here's a typical continental world, showing some of these features:


Here are a couple of non-tectonic worlds that I thought looked interesting:




Some new terrain features are possible now. For example, rarely, ocean ridges on small worlds can create planet-wrapping archipelagos and islands:


This was unplanned, but I like the effect, so I've left it in as an occasional possibility.

And you can of course view things like rivers on the globe:


- and climate types:


So now there are two problems I need to consider.

First, what engine should I use to display all of this? At the moment I'm just using OpenGL directly. This is fine for displaying simple objects such as the facets of my globe, but doing more elaborate effects is probably beyond my abilities. So far I've not been bothering about this as I wanted to work out whether I could create the terrain etc. of the planets first, and worry about how to display them later. But obviously with this method I can't do things like apply shadows, which means that they don't look as nice as my 2D maps that have the faux shading effect. So I'm wondering whether to use an existing engine such as Irrlicht to render the globe, which might allow me to do more. But then of course I'd have to learn how to do that...

Second, what about the regional maps? As things stand, I haven't implemented them at all yet in this new version. The actual generation of them shouldn't be too tricky. (I know I will regret typing that! But at the moment I think it should be fairly straightforward to convert the existing regional map creation routines to work with the spheres.) The problem is how to display them. One option is to keep the system of a zoomed-in mode, where the region is displayed as a 2D map, just as it is now. That would be very straightforward. But consider again what each region represents:


Each tile here is a region (supposing this is an Earth-sized world). Now suppose we zoom in on one in the middle of the "face" that is facing us. All is fine - it can be displayed in the zoomed-in screen, and we can scroll around to north, south, east, and west. But suppose we keep going north and find ourselves on the "face" that's on the top of the cubesphere. Scrolling around here won't be taking us north, south, east, and west any more, at least not in any consistent way. Suppose we now scroll to the right and go down the "face" to the right of this image. When we started on the first face, the top of the map was pointing to the north. But now it's pointing east. Things get even worse if we try to navigate around one of the points where three "faces" meet.

All of this comes from the fact that the world isn't really a sphere at all, but a cube, and if we display the regional map in 2D form it's going to be very hard to conceal this fact.

So the alternative is not to do it that way at all. Instead, we could allow the user to zoom gradually in on the globe, generating the regional maps as they do so, and then display those maps directly on the globe itself. So as you zoom in on the map you would see the regional-level details popping in once it's close enough.

There are two problems with this. The first is that it's hard! We'd have to be able to generate regional terrain on the fly as the user is moving around the globe, and keep track of which regions have been generated, which ones need to be generated, and be able to paste them onto the right bit of the globe. All of this is theoretically possible but could be a nightmare to implement.

The second problem is that some tiles would get distorted. Look again at the image above, and in particular the regions at the corners. We get away with the distortion at these points at global scale, but I worry that at regional scale it would look pretty bad. Mountains and rivers, in particular, would look unnaturally stretched.

So I'm not sure what to do about this. The next job is therefore probably to convert the regional map generating parts of the program and try pasting the generated maps onto the globe to see how they look.

2 comments:

  1. Wow, looks great! Are you going to update the GitHub repo that I cloned awhile ago? It looks like you're using a "cube sphere".

    Have you considered using an icosphere? It should have less distortion, though you may not want to rewrite everything at this point.

    For the rendering, you can get very far with OpenGL if you switch to using a modern pipeline with custom shaders. You can add shadows and all sorts of effects. At this point it may be easier to implement this rather than switching to another game engine.

    ReplyDelete
  2. Yes, I'll fork the project so I can keep the existing code available and put the revised version up as well. That way people can tinker with the 2D and 3D versions as they like.

    An icosphere would indeed be more accurate but I can't even imagine trying to work with triangular faces! The cubesphere seems to work well enough so I'll be sticking with that.

    I'll definitely try tinkering further with OpenGL. Since I'm basically only showing a single object which doesn't change, bringing in a whole engine might be overkill anyway.

    ReplyDelete