Search code examples
pythonnumpynoiseprocedural-generationperlin-noise

How to normalize Perlin Noise Values to range [0, 1]?


I am using a numpy array to hold Perlin Noise values. I have been told that Perlin Noise values in a 2D array are in the range [-0.7, 0.7] respectively, but this doesn't seem to be true. At least not for Caseman's "noise" library when I adjust the parameters for octaves, persistence, and lacunarity.

I would use a different library, except I can't find any for python that will run anywhere near as fast. Also, the typical formula for normalizing a value to range [0, 1] doesn't seem to work here regardless. Even If I get the min/max values of the unmodified noise, it still doesn't give me the value range I want. I just have to guess what to use for the min/max values until the range is roughly [0, 1].

How can I normalize Perlin Noise values to range [0, 1]?

import noise
import numpy
import sys

def __noise(noise_x, noise_y):
    """
    Generates and returns a noise value normalized to (roughly) range [0, 1].

    :param noise_x: The noise value of x
    :param noise_y: The noise value of y
    :return: float
    """

    value = noise.pnoise2(noise_x, noise_y, 8, 1.7, 2)
    # Normalize to range [0, 1]
    value = numpy.float32((value + 0.6447) / (0.6697 + 0.6447))

    return value


map_arr = numpy.zeros([900, 1600], numpy.float32)

for y in range(900):

    for x in range(1600):

        noise_x = x / 1600 - 0.5
        noise_y = y / 900 - 0.5

        value = __noise(noise_x, noise_y)
        map_arr[y][x] = value

for row in map_arr:
    for num in row:
        sys.stdout.write(str(num) + " ")
    print("")

Solution

  • map_arr = (map_arr - map_arr.min()) / (map_arr.max() - map_arr.min()) (taking advantage of numpy broadcasting and vectorisation) should be sufficient.