So, recently I've been learning procedural generation stuff (Perlin noise specifically) and I've kind of hit a wall. enter image description here This is the result that I've seen everyone get, but this is what I'm getting, enter image description here

This is my code, (I'm using python):

import random
import math
import PIL.Image

class Noise:

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def lerp(self, start, stop, t):
        return start*(1-t) + (stop*t)

    def smoothstep(self, t):
        return 3*(t**2) - 2*(t**3)

    def gradients(self):
        grads = []
        for _ in range(4):
            x = random.randrange(0, 361)
            y = random.randrange(0, 361)
            grads.append((math.cos(x), math.sin(y)))
        return grads

    def cvectors(self):
        botleft = (self.x, self.y)
        botright = (self.x-1, self.y)
        topleft = (self.x, self.y-1)
        topright = (self.x-1, self.y-1)
        cvecs = [botleft, botright, topleft, topright]
        return cvecs

    def makenoise(self):
        dot = []
        grads = self.gradients()
        cvecs = self.cvectors()
        for i in range(4):
            (x, y) = cvecs[i]
            (a, b) = grads[i]
        st = self.lerp(dot[0], dot[1], self.smoothstep(x))
        uv = self.lerp(dot[2], dot[3], self.smoothstep(x))
        stuv = self.lerp(st, uv, self.smoothstep(self.y))
        return stuv

    size = 128
    img = PIL.Image.new('L', (size, size))
    for x in range(size):
        for y in range(size):
            perlin = Noise(random.uniform(0, 1), random.uniform(0, 1))
            img.putpixel(tuple([x, y]), perlin.makenoise())

This is just a guess, but I feel like it's a scaling issue. Thanks in advance, and apologies, as well, for the horrible code.


2 Answers 2


Instead of passing in some random points to your noise function, you probably want to pass the X and Y coordinates of the pixel scaled in, try something like perlin = Noise(x /128.0, y /128.0)

  • \$\begingroup\$ I've tried it before, it gives a black tile. Completely black. \$\endgroup\$
    – JAW3112
    Commented Feb 11, 2020 at 15:14
  • 1
    \$\begingroup\$ Are you sure you weren't actually doing integer division and only sampling Noise(0, 0) forever? \$\endgroup\$
    – user35344
    Commented Feb 11, 2020 at 15:31
  • \$\begingroup\$ you're right about the Noise(0, 0) part, but that's because of the int(makenoise()) part since. Then a new question arises, how do I scale the values? \$\endgroup\$
    – JAW3112
    Commented Feb 11, 2020 at 17:31
  • \$\begingroup\$ So ask a new question. \$\endgroup\$
    – user35344
    Commented Feb 11, 2020 at 18:02

There is a noise module for python which you can install from pypi using pip. you can then import it and use its perlin noise function:

import noise
from noise import *

seed = random.randint(100)

num = noise.pnoise2(x/15, y/15, octaves=1 base=seed)

That is what I am using for my game to generate a tilemap of islands and oceans.


You must log in to answer this question.

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