Có hai phần để tạo ra tiếng ồn fBm có thể điều chỉnh liền mạch như thế này. Trước tiên, bạn cần làm cho chức năng tiếng ồn Perlin có thể điều chỉnh được. Đây là một số mã Python cho một hàm nhiễu Perlin đơn giản hoạt động với bất kỳ khoảng thời gian nào lên tới 256 (bạn có thể mở rộng nó một cách tầm thường bao nhiêu tùy thích bằng cách sửa đổi phần đầu tiên):
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))
Tiếng ồn Perlin được tạo ra từ một tập hợp các "phụ" nhỏ, là sản phẩm của một gradient được định hướng ngẫu nhiên và một hàm dự phòng đa thức tách rời. Điều này mang lại một vùng dương (màu vàng) và vùng âm (màu xanh)
Các phần tử có phạm vi 2x2 và được tập trung vào các điểm mạng nguyên, do đó, giá trị của nhiễu Perlin tại mỗi điểm trong không gian được tạo ra bằng cách tính tổng các phần phụ ở các góc của ô mà nó chiếm.
Nếu bạn thực hiện bọc hướng gradient với một khoảng thời gian, thì tiếng ồn sẽ tự ngắt hoàn toàn với cùng một khoảng thời gian. Đây là lý do tại sao đoạn mã trên lấy tọa độ mạng modulo trong khoảng thời gian trước khi băm nó thông qua bảng hoán vị.
Bước khác, là khi tính tổng quãng tám, bạn sẽ muốn chia tỷ lệ thời gian với tần số của quãng tám. Về cơ bản, bạn sẽ muốn mỗi quãng tám xếp toàn bộ hình ảnh chỉ một lần, thay vì nhiều lần:
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
Đặt nó cùng nhau và bạn nhận được một cái gì đó như thế này:
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")
Như bạn có thể thấy, điều này thực sự gạch liền mạch:
Với một số điều chỉnh nhỏ và ánh xạ màu, đây là hình ảnh đám mây được xếp theo tỷ lệ 2x2:
Hi vọng điêu nay co ich!