The intent of this project was to
- Get more experience in UE5
- Experiment with Landscapes
- Do something cool
The Stormlight Archive is a high fantasy series. The primary setting of the first book is a barren landscape of crevasses and plateaus
I wanted to find a way to mimic this landscape. It would be my first foray into generating an open world, and I hoped to utilize the new Unreal Engine features: Nanite and World Partition.
The first thing I looked into was heightmaps. Unreal has a nifty feature for generating landscapes from 16 bit grayscale images.
I figured this would be a good starting point for generating a landscape. Next on the list was actually generating the Heightmap.
After searching for some inspiration, I finally remembered Voronoi Diagrams from my computational geometry class.
With enough tweaking, this would work nicely for the procedural aspect I was looking for. I didn't feel like programming my own Voronoi library, so I looked for one. [This one] claimed to be faster than many others, (and was the first c++ one to show on google) so I decided to use it.
After downloading it and running the boilerplate, I had to find a graphics library that would let me draw the voronoi diagram in a way that mimicked a Heightmap. I downloaded SDL first, and got a working image out of it!
Unfortunately for me, SDL turned out to be a little too low level for what I was looking for. Outputting an image required an additional library, increasing line thickness required a different library, etc. I looked for a simpler, but more feature rich graphics library to replace it. I tried Cairo, and then SFML. SFML turned out to be easier to simply replace the SDL functions in the existing code.
Initial imports from the Voronoi Diagram had some jagged artifacts. This was to be expected, especially when compared directly to the real heightmaps.
What the real heightmaps have is a gradient, even on a harsh edge. One way to solve this problem is to supersample, AKA generate the image in a high resolution, and then lower the resolution. I may try this later, but for now, I simply generate a gradient line.
This smoothed out the edges a great deal. However, I'm not sure how much smoothing is possible. One limitation of SFML is that it doesn't support grayscale 16 bit output. It's just drawing on an RGB scale. Therefore, it is only an 8 bit scale. That's 65,536 states reduced to 256, an over 99% loss.
Actually, just figuring this out while writing this, but I suppose I can make the image in Red/Green Scale, and then convert that to 16 bit Grayscale. This might require an OpenGL fragment shader of some kind. That'll be a nice project.
Regardless, I'll work with what I have for now.
The next thing I added was some variance to the heights of the plateaus, to reduce the uniformity of the terrain. Relatively simple, just fill each cell with a random value.