Ada dua bagian untuk membuat suara fBm mulus tileable seperti ini. Pertama, Anda perlu membuat fungsi noise Perlin itu sendiri tileable. Berikut adalah beberapa kode Python untuk fungsi noise Perlin sederhana yang bekerja dengan periode hingga 256 (Anda dapat memperpanjangnya sesering mungkin dengan memodifikasi bagian pertama):
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 noise dihasilkan dari penjumlahan "surflets" kecil yang merupakan produk dari gradien berorientasi acak dan fungsi falloff polinomial yang dapat dipisahkan. Ini memberikan wilayah positif (kuning) dan wilayah negatif (biru)
Surflets memiliki luas 2x2 dan berpusat pada titik kisi integer, sehingga nilai kebisingan Perlin pada setiap titik dalam ruang dihasilkan dengan menjumlahkan surflets di sudut sel yang ditempati.
Jika Anda membuat arah gradien membungkus dengan beberapa periode, kebisingan itu sendiri kemudian akan membungkus dengan mulus dengan periode yang sama. Inilah sebabnya mengapa kode di atas mengambil modul koordinat kisi periode sebelum hashing melalui tabel permutasi.
Langkah lain, adalah ketika menjumlahkan oktaf Anda ingin skala periode dengan frekuensi oktaf. Pada dasarnya, Anda ingin setiap oktaf untuk memasang seluruh gambar hanya satu kali, daripada beberapa kali:
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
Gabungkan itu dan Anda mendapatkan sesuatu seperti ini:
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")
Seperti yang Anda lihat, ini memang benar-benar sempurna:
Dengan beberapa penyesuaian kecil dan pemetaan warna, berikut ini adalah gambar cloud ubin 2x2:
Semoga ini membantu!