I had never quite gotten island noise maps to work nicely, and part of that is that I’ve never studied the functions used for their construction. I understood the basic idea: start with noise elevation, push the borders down into water, push the center up into land. But that’s it. How do we push up and down? What are the best functions? On this page I look at several different functions and attempt to evaluate them.
To turn a noise height array into an island noise height array, I want to modify each elevation. For each location and original noise value, I need to generate a new noise value. That’s a lot to think about.
I decided to decompose this into two functions, distance and reshaping.
1 Distance#
Distance functions assign a distance value 0–1 to each location on the map. I had been using euclidean, diagonal, or manhattan for these. In 2021, KdotJPG recommended several others[2] on reddit, so I added some of them to this mix (note that I’m using 0 for center, 1 for border, while KdotJPG is using 1 for center, 0 for border).
How to read these charts: blue means close to 1, white means close to 0, and green is in between.
What are the properties I want?
- I’d like the borders of the map to all be dark blue, which will force the elevations down into water. This should be roughly a square.
- I’d like the center of the map to be white, which will force the elevations up into land (optionally). This should be roughly a circle. I’m not sure I want this
Of the distance functions I looked at, I think Square Bump and Trig Product from KdotJPG are the best choices, and of those two, Square Bump is simpler and faster to compute. I’m changing my recommendation to that (in 2022).
{ TODO: KdotJPG points out that some of these aren’t smooth; maybe I should plot the slope discontinuities }
{ TODO: KdotJPG says that if you don’t need to limit the island to a square, e.g. if it’s part of a larger world, you have more flexibility in which distance function to use – euclidean² would be reasonable ; I should try shrinking the euclidean radius, maybe with a slider }
2 Reshaping#
Reshaping functions take an input elevation 0–1 and produce an output elevation 0–1. I had been using Linear conversion, but also designed some others:
How to read these charts: each row is a reshaping function. The left side shows the reshaping near the map border; the right side shows the reshaping near the map center.
What properties do I want?
- Near the map border (left side of chart) I want the reshaper to always produce low elevations (water).
- Near the map center (right side of chart) I want want the reshaper to always produce high elevations (land). This is optional.
- In the rest of the map I want the reshaper to produce a mix of low and high elevations.
The Input reshaping function ignores the distance, and preserves the original noise. It doesn’t make an island. The Flat reshaping function forces an island, but ignores the noise. These two are included only for completeness. They are the two extremes.
Linear conversion is the average of Input and Flat. It’s easy to implement. On the left side, it reshapes 0–1 to 0–½, always water. On the right side, it reshapes 0–1 to ½–1, always land.
To get variety we need to suppress the elevation as little as possible. That means near the borders and near the center (maybe) we’d like to suppress the original elevation (closer to Flat’s horizontal line), but everywhere else we’d like to preserve the original elevation (closer to Input’s diagonal line). Linear conversion is the average of these two.
I made a visualization of how much the noise is suppressed (brown) vs preserved (cyan). The ideal output would be a wide ring, where the borders of the map suppresses noise, the center of the map suppresses noise (optional), and the rest of the map preserves noise.
- I designed Clamped to suppress in only some places. It’s switches between Input and Flat. In practice though it didn’t seem to work well.
So I think Smooth (quadratic bezier curve) is a better choice. But it has its own issues, especially in the center of the map. { maybe I need to apply this to octave 0 but not the other octaves? }
This diagram shows that Smooth is suppressing noise for much of the area that’s not near the borders or the center. Until seeing this visualization I didn’t realize it. So I designed Smooth2 and Smooth3, both of which suppress much less.
Problem: if you mix the octaves first (low frequencies for elevation, high frequencies for bumpiness), then it’s hard to suppress the elevation without also suppressing the bumpy features. Linear doesn’t have this problem, so it might be the simplest recommendation. I don’t know how to solve this problem yet.
{ TODO: I can pick different functions for the borders and the center, and it may make sense to pick Smooth for the borders but Linear for the center }
3 Comparison#
The real test of all of this is: what do the islands look like?! My old recommendations of {Euclidean, Diagonal, Manhattan} + Linear do produce reasonable islands, but I think my new recommendation of Square Bump + Smooth generates more interesting islands every time. Square Bump forces an island shape with the least distortion, and Smooth preserves most of the variation from the noise function. If you want a more solid shape you can either reduce your high frequency noise amplitudes or switch to Square Bump + Linear.
{ TODO: If you don’t need the map center to be land, you can use SmoothLow, which offers even more variety. Compare SmoothLow to Smooth in each column. }
4 TODO Open issues#
- As RuneVision on Twitter points out, the Smooth shaping function is also going to smooth out terrain bumpiness in the center of the map, and that’s probably not what I want. Maybe the reshaper should only apply to the first and second octaves? This is getting complicated.
- How the reshaper works in water and on land is currently symmetric, but probably shouldn’t be.
- As more than one person pointed out on twitter, which of these functions you want depends on your goals, and it may be hard for me to make a single recommendation. I do think KdotJPG’s SquareBump is a win for distance functions, but the shaping functions don’t have a clear winner.
5 TODO Bonus#
Just for fun, the Archipelago reshaping function pushes land up midway between the center and border of the map, forming a circular island chain. Adjusting it slightly up or down will increase or decrease the land mass. For this page I made the low end halfway between SmoothLow and Smooth, so it doesn’t force the entire mid-distance circle to be land.
Also just for fun, the Blob distance function tries to vary the distance based on the angle, similar to my blob logo. I think it doesn’t work well.