I am using noise and I can't get Perlin Noise working, only the Simplex Noise. So far I got this:

import noise

values = list()
string = str()
oct = 1

for y in range(20):
    print("[", end = "")
    for x in range(40):
        i = round(noise.snoise2(x, y, octaves = oct), 5)
        if i > 0.3:
            print("#", end = "")
            string = string + "#"
            print("-", end = "")
            string = string + "-"
    print("]\n", end = "")

When I try to use Perlin noise instead, I get a value of zero for every x & y.


A quick recap of how Perlin noise works:

It starts by finding the cell your sample point lands in within an integer lattice. From that it determines the integer points that define the corners of that cell. For each corner, it generates a pseudo-random gradient vector, and then computes the projection of your sample point's offset from the corner along this gradient vector. Interpolating those projections according to your sample position gives the final smooth noise value.

Diagram showing how Perlin noise works using gradient vectors at corner points

So, let's consider how this works when your sample lands directly on one of these corner points. The interpolation weight for all the other corners will be zero, and the projection onto this corner's gradient vector will also be zero, so the result is: zero.

At every set of integer coordinates, Perlin noise will give you a value of zero.

So, easy fix: don't sample at integer coordinates. Sampling at (x + 0.5, y + 0.5) for integers x & y will move your sample point from the corner to the center of the cell. You won't see much benefit of using a continuous noise function like Perlin noise that way though. Adjacent samples will have little correlation. If you want just a random number per tile, you could use a hashing function like Perlin noise uses internally to select a random gradient for each corner - skipping the overhead of doing it four times, computing dot products and interpolating the results.

Or, if you want continuity across multiple tiles, you should scale your sampling locations smaller than the feature size of the noise function. For instance, if you want large-scale features on the order of about 30 tiles wide, divide x & y by 30 to get a fractional sampling location that will gradually ramp up & down the hills and valleys within each grid cell of the noise function.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.