0
\$\begingroup\$

I'm generating my game's map using Perlin noise. It's an infinite 2D world with terrain data loaded on demand. I'm using Perlin noise to generate terrain. However, I've noticed that the Perlin noise implementation I'm using is periodic, and this is at a noticeable distance (repetition begins at about 400 tiles).

Many answers I've seen online involve sampling at a higher frequency, but this decreases the number of peaks and troughs in a given area. I'm not looking for layering techniques which only add more octaves, I need the variation to be along the entire range of the noise function. An example of what I mean:

This is an image of roughly what I have currently, which is basically what I want:

Increasing the sampling frequency yields this result, which is noticeably flatter:

Adding more octaves on top of that flatter noise makes it more jagged locally, but doesn't create peaks or troughs on the global level:

Is there a way to get a result like the first one with lots of peaks and troughs on a macro scale using Perlin noise, while keeping the period reasonably large, say, 5000 tiles?

\$\endgroup\$
0
0
\$\begingroup\$

Dynamic Implementation

Optimally, I would just use a Perlin-noise implementation which doesn't repeat so quickly, or at all. If speed isn't of utmost importance, then I don't see a reason that Perlin-noise can't be generated dynamically at runtime based on some non-repeating random number generator, rather than from a look up table.

Working with what you got

2D

You could try using the output of one Perlin noise function as the input to another - now you're sampling a point from 2-dimensional Perlin-noise-space and it'll be very unlikely to get repetition.

x += noise(time);
var y2 = noise(x);
Layered

You could also try layering outputs of two independent Perlin-noise functions, perhaps sampling them at different rates with different levels of octaves. $$ y = noise(time, octave) + noise(a *time + constant, b*octave) $$

More Control

If you really want to fine tune the feel of perlin noise -- in terms of adjusting the appearance of macroscopic vs microscopic features -- you could try manipulating the influence of noise at various "octaves".

You could give yourself complete control over this function using a Bezier curve or some other spline. Of course this would mean creating your own Perlin-noise inspired implementation, or modifying an existing algorithm.

\$\endgroup\$
1
  • \$\begingroup\$ "You could try using the output of one Perlin noise function as the input to another - now you're sampling a point from 2-dimensional Perlin-noise-space and it'll be very unlikely to get repetition." I don't understand what you're trying to say here. noise is a function which outputs a value in an interval, in my case between 0 and 0.5. By limiting the input of the second function to only these values, wouldn't repetition just happen more frequently? \$\endgroup\$ Aug 8 '21 at 8:02
0
\$\begingroup\$

Your issue is that it's tileable, and you don't want it to be, if I understand correctly? In that case, I would seek a noise implementation that isn't periodic, at least not on the scale of your world.

Secondly Perlin as a noise function is very square-aligned. It's an artifact of its fundamental inner workings that not enough people talk enough about. Take it with a grain of salt when sources recommend it with no caveats or clarifications. It's better generally to use a good implementation of a Simplex-type noise, or a Perlin that has its artifacts mitigated (e.g. through 3D domain rotation).

FastNoiseLite's noise functions are not periodic. You can take it and then use the OpenSimplex2 or OpenSimplex2S options. https://github.com/Auburn/FastNoiseLite/

p.s. In your second image where you describe increasing the sampling frequency, you actually have the frequency decreased, not increased. Doesn't affect the conclusion you came to, just the technicalities behind it.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .