Worley noise

sá. 30 mayo 2020

Worley noise is a noise function introduced by Steven Worley in 1996. In computer graphics it is used to create procedural textures, i.e. textures that are created automatically with arbitrary precision and do not have to be drawn by hand. Worley noise comes close to simulating textures of stone, water, or biological cells.

Basic algorithm

The basic idea is to take random points in space (2- or 3-dimensional) and then for every location in space take the distances dn to the nth-closest point (e.g. the second-closest point) and use combinations of those to control color information ( note that dn+1 > dn). More precisely:

  1. Randomly distribute feature points in space organised as grid cells. In practice this is done on the fly without storage (as a procedural noise). The original method considered a variable number of seed points per cell so as to mimic a Poisson distribution, but many implementations just put one.
  2. At run time, extract the distances dn from the given location to the nth-closest seed point. This can be done efficiently by visiting the current cell plus its neighbors.
  3. Noise W(x) is formally the vector of distances, plus possibly the corresponding seed ids, user-combined so as to produce a color.
Figure 1. Worley noise with 50 random points.

The code to obtain the above image is found here and is copied below:

from PIL import Image
from random import randint
import numpy as np

WIDTH, HEIGHT = 400, 400
n = 0
points = []
nPoints = 20
points = [np.array([randint(0,WIDTH),randint(0,HEIGHT)]) for i in range(nPoints)]

img = Image.new('RGB',(WIDTH,HEIGHT))

pixels = img.load()

for x in range(WIDTH):
    for y in range(HEIGHT):
        d = np.zeros(len(points))
        for i,point in enumerate(points):
            d[i] = ((point[0]-x)**2+(point[1]-y)**2)**0.5
        d.sort()
        c = int(d[n])
        pixels[x,y] = (c,c,c)

img.show()
img.save('Example.jpg','JPEG')