Sign in to follow this  

More seamless tiling Perlin noise

This topic is 3550 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm looking to add seamless tiling to my current implementation of the Perlin noise algorithm (scroll about half-way down for the code), and I can't quite figure it out. The only decent references I've found for this are the Perlin Noise FAQ and a recent post by Ysaneya. For ease of reference, here is the algorithm: Ftileable(x, y) = ( F(x, y) * (w - x) * (h - y) + F(x - w, y) * (x) * (h - y) + F(x - w, y - h) * (x) * (y) + F(x, y - h) * (w - x) * (y) ) / (w * h) I replaced the existing call to F(x, y) with the above logic, and now my noise looks terrible. Depending on how I tweak the input values, the "tiled" output varies between white noise and a mostly-solid color. What range should these values be in? Currently, x and y are always between 0.0 and the frequency of the current octave (i.e. 1.0, 2.0, 4.0, 128.0, etc.). w and h are both set to the frequency. Also, I'm assuming that it is okay to accumulate multiple octaves of this function. I'm not really sure what else to add, since my algorithm seems to match the one from the FAQ. Does anyone have any ideas on what I'm doing wrong?

Share this post


Link to post
Share on other sites
I'm starting to wonder if that algorithm is the best approach. Wouldn't it be better to have the noise generator use the same random gradients at the edges that need to be tileable? That way the points near the edge would automatically align themselves with that gradient.

Thoughts?

Share this post


Link to post
Share on other sites
I cant say much about the algorthim, but my question is why does anyone bother with generating perlin noise in this way when the result is better obtained by using a small, premade noise texture that can be filtered, tiled and scailed at will?

Share this post


Link to post
Share on other sites
I originally built a noise generator to build random maps. A pre-made texture wouldn't work for that. I figured it would be nice to reuse that code for procedural texture generation, rather than using my limited GIMP skills to come up with something similar.

Share this post


Link to post
Share on other sites
Success! The solution was actually quite simply, once I fixed a few other tiny bugs in my algorithm. For a given octave of noise, I use an array of gradients that is equal in length to the squared frequency of the octave. For example, generating a 2D noise map with a frequency of 8.0 would require 64 gradients. The indexes wrap around at the edges, so noise samples taken near them will be influenced by the gradients on the other side of the noise map.

When I accumulate multiple octaves of noise, I simply use a different set of gradients for each octave, each with a size that matches the octave's frequency.

Problems

  • The number of required gradients increases exponentially as octaves increase, assuming the frequency doubles with each octave. 10 or 11 octaves is pretty fast on my 2.33ghz Core2Duo, but anything beyond that is significantly slower. The 12th octave, for example, would require 16777216 (2^12 * 2^12 = 4096 * 4096 = 16777216) gradients.

  • Fractional frequencies can't be used. You can't generate an array with 2.5 gradients, so noise maps that use that frequency won't be tileable. I don't see this as a significant issue, though.

Possible improvements

  • Rather than use a distinct set of gradients for each octave, you could generate a single array with enough for the largest octave. The octaves with lower frequencies could simply use a subset of the large array.

  • Higher octaves don't really need the massive randomness that my current algorithm generates (come on, 16777216?!?). The gradient array length can actually be smaller than the frequency, as long as it is a divisor of the frequency (i.e. 4 gradients for frequency 8.0). Thus, you could set an upper limit for the array's length to something like 256. The noise would repeat beyond that frequency, but I doubt the user would notice the difference, unless you are generating phenomenally large noise maps.

Share this post


Link to post
Share on other sites
I just modified my algorithm to limit the gradient array length to 256, and the performance improvement was just as I expected. A noise map with 16 octaves was generated very quickly.

So, does anyone seem any downsides to this? Is there any reason for me to play with the algorithm mentioned in the Perlin Noise FAQ?

Share this post


Link to post
Share on other sites

This topic is 3550 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this