Hexagon Earth

    There appears to be a few different ways to partition a sphere into hexagons. Although it is impossible to do just hexagons, there are a few different ways to do it that involve some pentagons. Uber’s H3 - https://github.com/uber/h3 Subdivided Icosahedron - https://github.com/vraid/earthgen-old They were both interesting and seemed like the 2nd approach had less distorted hexagons, but I’ve decided to try using Uber’s open source H3 library due to its built in compact 64bit H3 Index representation that makes traversing cells in various resolutions and areas easy without creating lots of data structures. It has some quirks like outputting cell boundaries that have up to 10 points near the pentagons, and hexagon shapes getting noticeably distorted in some areas. But it also automatically applies Dymaxion Orientation that places all pentagons under the ocean. Apparently Star Link may be also using H3 to define their service area cells, which is also interesting.

How H3 subdivides a sphere

How H3 subdivides a sphere (source)

    To render elevation, I was able to find a public earth DEM(Digital Elevation Model) from NOAA (soruce) and tried rendering the data combined with H3 using open source Godot engine. The data has a weird copyright notice that says it is not subject to copyright protection within the U.S. but foreign copyrights MAY apply. I wasn’t able to get a response trying to clarify what limitations MAY brings so I’ll be switching data sources to a different source. Fortunately I found a even higher resolution data source without a confusing license from GEBCO (source).

    To improve rendering performance in Godot, I ended up using MultiMesh to do instancing. One challenge was hexagons not being uniform and some being significantly distorted. So to not create gaps and overlaps, I ended up creating a texture that stored all hexagon corner positions so the vertex shader can fetch the correct corner positions using INSTANCE_ID. It would be better if I could just use per-instance data of MultiMesh, but I couldn’t fit all the information required in per-instance transform + color + custom, hence a texture. Another challenge was integrating C++ H3 library with Godot. There were 2 options, GDNative vs. creating a module. I ended up choosing the latter since I read GDNative didn’t work with HTML5 export for now, and modules appeared to have more access to engine internals. Downside is it requires building the whole engine every time I change something, but so far it’s been okay …

Enjoy!
Nov 2021
Shovely Dev