Bu şekilde sorunsuz bir şekilde eğilebilir fBm sesi çıkarmanın iki parçası var. Öncelikle, Perlin gürültüsü işlevini kendiliğinden eğilebilir hale getirmeniz gerekir. İşte 256'ya kadar olan herhangi bir periyodla çalışan basit bir Perlin gürültü fonksiyonu için bazı Python kodları (ilk bölümü değiştirerek istediğiniz kadar önemsiz şekilde uzatabilirsiniz):
import random
import math
from PIL import Image
perm = range(256)
random.shuffle(perm)
perm += perm
dirs = [(math.cos(a * 2.0 * math.pi / 256),
math.sin(a * 2.0 * math.pi / 256))
for a in range(256)]
def noise(x, y, per):
def surflet(gridX, gridY):
distX, distY = abs(x-gridX), abs(y-gridY)
polyX = 1 - 6*distX**5 + 15*distX**4 - 10*distX**3
polyY = 1 - 6*distY**5 + 15*distY**4 - 10*distY**3
hashed = perm[perm[int(gridX)%per] + int(gridY)%per]
grad = (x-gridX)*dirs[hashed][0] + (y-gridY)*dirs[hashed][1]
return polyX * polyY * grad
intX, intY = int(x), int(y)
return (surflet(intX+0, intY+0) + surflet(intX+1, intY+0) +
surflet(intX+0, intY+1) + surflet(intX+1, intY+1))
Perlin gürültüsü, rastgele yönelimli bir gradyanın ve ayrılabilir bir polinom ayrılma fonksiyonunun ürünü olan küçük "surfletlerin" toplamından üretilir. Bu pozitif bölge (sarı) ve negatif bölge (mavi) verir
Sörfçüler 2x2 boyutundadır ve tam sayı kafes noktalarına odaklanmıştır, bu nedenle uzaydaki her bir noktadaki Perlin gürültüsünün değeri, sörfçüleri işgal ettiği hücrenin köşelerinde toplayarak üretilir.
Degrade yönlerinin bir süre sarılı kalmasını sağlarsanız, gürültünün kendisi de aynı süreyle sorunsuz şekilde sarılır. Bu yüzden yukarıdaki kod örgü koordinatını permütasyon tablosundan geçirmeden önceki süreyi modulo olarak alıyor.
Diğer adım, oktavları toplarken, dönemi oktavın frekansı ile ölçeklendirmek isteyeceksinizdir. Temel olarak, her oktavın tüm görüntüyü birden çok kez değil, yalnızca bir kez döşemesini istersiniz:
def fBm(x, y, per, octs):
val = 0
for o in range(octs):
val += 0.5**o * noise(x*2**o, y*2**o, per*2**o)
return val
Bunu bir araya getirin ve şöyle bir şey olsun:
size, freq, octs, data = 128, 1/32.0, 5, []
for y in range(size):
for x in range(size):
data.append(fBm(x*freq, y*freq, int(size*freq), octs))
im = Image.new("L", (size, size))
im.putdata(data, 128, 128)
im.save("noise.png")
Gördüğünüz gibi, bu gerçekten sorunsuz bir şekilde döşeniyor:
Bazı küçük ince ayar ve renk eşlemelerinde, işte 2x2 döşenmiş bir bulut resmi:
Bu yardımcı olur umarım!