May 20, 2016

How to achieve seamless infinite random terrain

I've made a prototype of an infinite terrain system for a project I'm working on. This is how it looks like:

The terrain is infinite and random, and I'm using Perlin Noise to generate it. If you are interested in making something similar then you should watch the beginning of this tutorial series: Procedural Landmass Generation.

To be able to distinct between sea, sand, land, and mountain, you have to discretize the continuous noise into squares because you can't have an endless amount of squares. So you will end up with something looking like this:

This is one so-called chunk, which the terrain is made up of. To generate an endless terrain you just add more chunks to coordinates around this square. But if you generate the noise at another position you will realize that the noise will not be the same.

In the image above I've moved the terrain left, and you can see that the bottom of the mountain now consists of 2 squares and not 3 as before the movement. Where did the last square go? The answer is that it's there but I've discretized the continuous noise at another position, so it now believe there's land where it used to be a mountain. This is how discretization looks like:

You discretize at the center of the square (the blue lines). But if you move the noise (the curve) then the noise in the same square may have changed. This is not a problem if you are generating terrain like the terrain in Minecraft where one square doesn't really depends on what's going on in the next square, so you will not notice strange seams. But if you're using an algorithm like Marching Squares to smooth the otherwise blocky terrain, then you will need to know what's going on in the next square, or you will end up with very ugly seams. To solve this mess you have to generate noise in a square with a border which is 1 longer than the original size of the chunk:

The values in the border have to be the same as if you had generated it in another of the surrounding squares. So first you are generating the noise for the center of the square, which is the same values as you generated before creating a border. Then in the right border (which is one of the borders you added), you generate noise as if you had moved the center of the square to the position of the square to the right. So in the right border you have to have the same noise as the noise in the left side (without a border) of the square to the right of the square you are generating noise for:

...and the opposite for the left side (and the top and bottom border):

And when you have generated the extra noise for the 4 borders, then you generate the mesh with the Marching Squares algorithm (or whatever algorithm you have). Finally you simply cut the extra border you added, and you will end up with a perfectly seamless endless terrain:

You can test the results here.

No comments:

Post a Comment