Home » How do you generate tileable Perlin noise?

How do you generate tileable Perlin noise?

Solutons:


There’s two parts to making seamlessly tileable fBm noise like this. First, you need to make the Perlin noise function itself tileable. Here’s some Python code for a simple Perlin noise function that works with any period up to 256 (you can trivially extend it as much as you like by modifying the first section):

import random
import math
from PIL import Image

perm = range(256)
random.shuffle(perm)
perm += perm
dirs = [(math.cos(a * 2.0 * math.pi / 256),
         math.sin(a * 2.0 * math.pi / 256))
         for a in range(256)]

def noise(x, y, per):
    def surflet(gridX, gridY):
        distX, distY = abs(x-gridX), abs(y-gridY)
        polyX = 1 - 6*distX**5 + 15*distX**4 - 10*distX**3
        polyY = 1 - 6*distY**5 + 15*distY**4 - 10*distY**3
        hashed = perm[perm[int(gridX)%per] + int(gridY)%per]
        grad = (x-gridX)*dirs[hashed][0] + (y-gridY)*dirs[hashed][1]
        return polyX * polyY * grad
    intX, intY = int(x), int(y)
    return (surflet(intX+0, intY+0) + surflet(intX+1, intY+0) +
            surflet(intX+0, intY+1) + surflet(intX+1, intY+1))

Perlin noise is generated from a summation of little “surflets” which are the product of a randomly oriented gradient and a separable polynomial falloff function. This gives a positive region (yellow) and negative region (blue)

Kernel

The surflets have a 2×2 extent and are centered on the integer lattice points, so the value of Perlin noise at each point in space is produced by summing the surflets at the corners of the cell that it occupies.

Summation

If you make the gradient directions wrap with some period, the noise itself will then wrap seamlessly with the same period. This is why the code above takes the lattice coordinate modulo the period before hashing it through the permutation table.

The other step, is that when summing the octaves you will want to scale the period with the frequency of the octave. Essentially, you will want each octave to tile the entire just image once, rather than multiple times:

def fBm(x, y, per, octs):
    val = 0
    for o in range(octs):
        val += 0.5**o * noise(x*2**o, y*2**o, per*2**o)
    return val

Put that together and you get something like this:

size, freq, octs, data = 128, 1/32.0, 5, []
for y in range(size):
    for x in range(size):
        data.append(fBm(x*freq, y*freq, int(size*freq), octs))
im = Image.new("L", (size, size))
im.putdata(data, 128, 128)
im.save("noise.png")

Tileable fBm Noise

As you can see, this does indeed tile seamlessly:

fBm Noise, Tiled

With some small tweaking and color mapping, here’s a cloud image tiled 2×2:

Clouds!

Hope this helps!

Here’s one rather clever way that uses 4D Perlin noise.

Basically, map the X coordinate of your pixel to a 2D circle, and the Y coordinate of your pixel to a second 2D circle, and place those two circles orthogonal to each other in 4D space. The resulting texture is tileable, has no obvious distortion, and doesn’t repeat in the way that a mirrored texture would.

Copy-pasting code from the article:

for x=0,bufferwidth-1,1 do
    for y=0,bufferheight-1,1 do
        local s=x/bufferwidth
        local t=y/bufferheight
        local dx=x2-x1
        local dy=y2-y1

        local nx=x1+cos(s*2*pi)*dx/(2*pi)
        local ny=y1+cos(t*2*pi)*dy/(2*pi)
        local nz=x1+sin(s*2*pi)*dx/(2*pi)
        local nw=y1+sin(t*2*pi)*dy/(2*pi)

        buffer:set(x,y,Noise4D(nx,ny,nz,nw))
    end
end

Ok, I got it. The answer is to walk in a torus in 3D noise, generating a 2D texture out of it.

torus wraps 2 dirs

Code:

Color Sky( double x, double y, double z )
{
  // Calling PerlinNoise3( x,y,z ),
  // x, y, z _Must be_ between 0 and 1
  // for this to tile correctly
  double c=4, a=1; // torus parameters (controlling size)
  double xt = (c+a*cos(2*PI*y))*cos(2*PI*x);
  double yt = (c+a*cos(2*PI*y))*sin(2*PI*x);
  double zt = a*sin(2*PI*y);
  double val = PerlinNoise3D( xt,yt,zt, 1.5, 2, 12 ) ; // torus

  return val*val*cloudWhite + 2*val*(1-val)*gray + (1-val)*(1-val)*skyBlue ;
}

Results:

Once:

tilable sky

And tiled:

showing it tiles

Related Solutions

What if ‘kill -9’ does not work?

kill -9 (SIGKILL) always works, provided you have the permission to kill the process. Basically either the process must be started by you and not be setuid or setgid, or you must be root. There is one exception: even root cannot send a fatal signal to PID 1...

Repeat a Unix command every x seconds forever

Try the watch command. Usage: watch [-dhntv] [--differences[=cumulative]] [--help] [--interval=<n>] [--no-title] [--version] <command>` So that: watch -n1 command will run the command every second (well, technically, every one second plus the time...

How can I specify the position for a new column in PostgreSQL?

ALTER TABLE ADD COLUMN will only add the new column at the end, as the last one. In order to create a new column in another position you need to recreate the table and copy the data from the old/current table in this new table. You'll need to recreate the table...

Java and switch case

As said here, switch works with the byte, short, char, and int primitive data types. It also works with enumerated types and a few special classes that "wrap" certain primitive types: Character, Byte, Short, and Integer. The Java switch statement is compiled...

How to “force” users to upgrade their browser?

Updated Answer - March 2013 Since this answer was posted on November 2012, Google has discontinued this plugin. While it might still work as of today (March, 2014) there is no guarantee of it working in the future. As of January 2014, support for Chrome Frame...

Splitting credit card number fields into four different inputs

I would generally always opt for the simplest solution. In this case, one single field for the user to type into. With split fields, such as the 4-box one you propose it adds in an extra cognitive load to the user. "Do I need to manually jump to each field?"...

Is coffee a good excuse for a slow application start-up time?

To me, the basic logic is this: It's better to have a fast app than a slow app. While there are many studies that show that faster applications provide better UX, it seems pretty axiomatic to me. I mean, generally in life if we want something done, then we...

Why are terminal consoles still used?

From a UX perspective, terminal consoles have a few key advantages over GUI's. These advantages are rarely relevant to end-users, which is why CLI's are used almost exclusively by technical users and "power users" these days. Things done in a terminal are...

Should you always minimize cognitive load?

No. It is not always appropriate to minimize cognitive load. Minimizing cognitive load is not the goal of usability, human factors, UX, or the user centered design process in general. It is about "good design", and good design is not always the simple design....

How do you give your user options without overloading them?

While Charles's Answer shows some great UIs, I wanted to add the UX that Directory Opus uses for the same action, which I find very good as well. Simple on the surface with advanced options tucked away after a click. . Clicking on the Dropdowns results in these...

Why is it important to focus on user needs as opposed to requests?

Users are bad at asking for what they need and great at asking for what they want. Anecdotal evidence from my own recent experience: We have a department that asked for a button that would generate a PDF report about some data. A few months later they asked for...

Is Markdown Friendly Enough for Non-Technical Users?

I know I'm coming to this thread rather late, but I actually have run usability tests comparing a WYSIWYG editor (iWeb) to a non-WYSIWYG editor based mostly on markdown. Here's what I've found that users struggle with when using markdown: Tags that require...

Why do numpads on keyboards and phones have reversed layouts?

There's this humongous article called Keyboard Trivia that has collected many of the theories and stories. The summary of facts: Touch-tone key pad was designed to mimic the rotary dial with the "1" on top and the 7-8-9 on the bottom, and AT&T conducted...

Why are radio buttons circles?

Square was easy The earliest appearance of circular radio buttons that I can find is in Apple Macintosh System 4 (1987). Prior to that Mac OS used squares with beveled corners, which was probably just computationally easier to draw and better-looking on...

Why might right aligned field labels be better?

Luke Wroblewski wrote about this in Top, Right or Left Aligned Form Labels (April, 2007). In it, he references eyetracking data from an article by Matteo Penzo called Label Placement in Forms (July, 2006). Matteo drew several conclusions from this study,...

Which way should be “on” for a switch?

It appears to be dependent on country or region, as Wikpedia states in the article Light Switch: Up or down The direction which represents "on" also varies by country. In the USA and Canada and Mexico and the rest of North America, it is usual for the "on"...

Who needs an external on/off Wi-Fi button?

Security A hardware radio switch has security benefits to it in that when it is off, you know for a fact that nothing is connected to your laptop wirelessly. The radio switch usually turns off all wireless communication, including Bluetooth and 3G. I have heard...