Saya tidak mengikuti kode Anda dengan tepat, tetapi di sini ada deskripsi yang disederhanakan dari algoritma yang kira-kira akan mencapai efeknya (berdasarkan gambar yang Anda posting).
Penjelasan berikut ini bukan versi super dioptimalkan, tetapi adalah salah satu yang jelas secara konsep (saya harap). Setelah Anda menjalankannya, Anda dapat mengoptimalkannya (cukup drastis, sebenarnya).
- Hasilkan n lapisan noise acak yang seragam (hanya piksel skala abu-abu acak).
- Sekarang sampel masing-masing dengan sampling setiap, 1, 2, 4, 8, ... 2 ^ (n-1) piksel, dan interpolasi piksel menengah. Setiap lapisan lebih halus dari yang sebelumnya.
- Sekarang skala ini dengan faktor 1, 2, 4, 8, dll. Setiap lapisan lebih gelap dari yang sebelumnya.
- Tambahkan semua ini bersama-sama.
- Normalisasikan dengan membagi setiap piksel dengan (1 + 2 + 4 + 8 + ... 2 ^ (n-1)).
Langkah yang sulit adalah langkah pengambilan sampel dan interpolasi. Misalkan kita berada di layer melewatkan sampling setiap m-th pixel. Ini adalah ide dasar untuk m> 1 (jika m adalah 1, kita menggunakan gambar apa adanya):
for each pixel x and y
left_sample_coord = m *(x / m) //(integer division, automatically truncated)
right_sample_coord = (left_sample_point + m) % image_width
top_sample_point = m*(y / m)
bottom_sample_coord = (top_sample_point + m) % image_height
horizontal_weight = (x - left_sample_point) / (m - 1)
vertical_weight = (y - top_sample_point) / (m - 1)
sample_top_left = image(left_sample_coord, top_sample_point)
//and the same for the other four corners
//now combine the top two points
top_interpolate = sample_top_left * horizontal_weight + sample_top_right * (1-horizontal_weight)
//now combine the bottom two points
bottom_interpolate = sample_bottom_left * horizontal_weight + sample_bottom_right * (1-horizontal_weight)
//and combine these two last obtained values
smooth_noise(x, y) = top_interpolate * vertical_weight + bottom_interpolate * (1 - vertical_weight)
Beberapa tips:
- Hasil dari algoritma di atas mungkin tampak agak pudar. Anda dapat mengurangi efek ini dengan menggunakan lapisan noise yang sama untuk semua lapisan, atau meningkatkan kontras gambar setelahnya.
- Algoritma di atas menggunakan interpolasi linier, tetapi interpolasi kosinus (melakukan pencarian) memberikan hasil yang jauh lebih baik.
- Memungkinkan untuk melihat layer Anda secara terpisah selama semua bagian dari algoritma. Ini akan membantu Anda membersihkan bug dengan cepat.