Lines 64
##### Keywords
noise (2) perlin (2)
##### Permissions
Owner: Stou S.
Viewable by Everyone
Editable by All Siafoo Users
Solve a problem – Filter by language, license, keyword, owner, or search text to find code & info fast.

# Fast Improved Perlin Noise 0

 In Brief A NumPy rewrite of JD Marble's 2D Improved Perlin Noise Python snippet. This version is roughly 3 to 10 times faster than the pure Python version above but it does require NumPy.... more
 Language NumPy
# 's
` 1from numpy import array, abs, arange, dot, int8, int32, floor, fromfunction,\ 2                  hypot, ones, prod, random, indices, newaxis, poly1d 3import Image 4 5class PerlinNoise(object): 6 7    def noise(self, coords): 8 9        ijk = (floor(coords) + self.idx_ar).astype(int8)1011        uvw = coords - ijk1213        indexes = self.P[ijk[:,:, self.order - 1]]1415        for i in range(self.order - 1):16            indexes = self.P[(ijk[:,:, i] + indexes) % len(self.P)]1718        gradiens = self.G[indexes % len(self.G)]19#        gradiens = self.G[(ijk[:,:, 0] + indexes) % len(self.G)]20        21        res = (self.drop(abs(uvw)).prod(axis=2)*prod([gradiens, uvw], axis=0).sum(axis=2)).sum(axis=1)2223        res[res > 1.0] = 1.024        res[res < -1.0] = -1.02526        return ((res + 1)*128).astype(int8)2728    def getData(self, scale=32.0):29        return self.noise(indices(self.size).reshape(self.order, 1, -1).T / scale)3031    def getImage(self, scale=32.0):32        return Image.frombuffer('L', self.size[:2], 33                                self.getData(scale)[ : self.size[0]*self.size[1]],34                                'raw', 'L', 0, 1)3536    def saveImage(self, fileName, scale=32.0):37        im = self.getImage(scale)38        im.save(fileName)3940    def __init__(self, size=None, n=None):4142        n = n if n else  256        43        self.size = size if size else (256, 256)4445        self.order = len(self.size)46        47        # Generate WAY more numbers than we need48        # because we are throwing out all the numbers not inside a unit49        # sphere.  Something of a hack but statistically speaking50        # it should work fine... or crash.51        G = (random.uniform(size=2*self.order*n)*2 - 1).reshape(-1, self.order)5253        # GAH! How do I generalize this?!54        #length = hypot(G[:,i] for i in range(self.order))5556        if self.order == 1:57            length = G[:,0]58        elif self.order == 2:59            length = hypot(G[:,0], G[:,1])60        elif self.order == 3:61            length = hypot(G[:,0], G[:,1], G[:,2])62        63        self.G = (G[length < 1] / (length[length < 1])[:,newaxis])[:n,]64        self.P = arange(n, dtype=int32)65        66        random.shuffle(self.P)67        68        self.idx_ar = indices(2*ones(self.order), dtype=int8).reshape(self.order, -1).T69        self.drop = poly1d((-6, 15, -10, 0, 0, 1.0))7071if __name__ == "__main__":72    # 1D Noise73    n = PerlinNoise(size=(1, 128))74    n.saveImage('PerlinNoise-1D.png')7576    # 2D Noise77    n = PerlinNoise(size=(128, 128))78    n.saveImage('PerlinNoise-2D.png')7980    # 3D Noise81    # It is preferable to get the 3D noise data and manipulate it yourself82    # since saving it as an image might have some strange results (for non-1 3d dimenison83    n = PerlinNoise(size=(128, 128, 1))84    n.saveImage('PerlinNoise-3D.png')`

A NumPy rewrite of JD Marble's 2D Improved Perlin Noise Python snippet. This version is roughly 3 to 10 times faster than the pure Python version above but it does require NumPy.

The code supports 1D, 2D and 3D noise... it should be fairly easy to extend it to higher dimensions.

Warning

Be careful with 3D noise, it's fairly memory intensive

For more information about Perlin noise, check out Making Noise and Matt Zucker's excellent Perlin noise math FAQ

In the following picture, the 3D noise values are used to lookup colours from a transfer function and the whole thing is rendered using the wxPython and PyOpenGL Volume Rendering Skeleton