Я точно не дотримуюся вашого коду, але ось спрощений опис алгоритму, який дозволить приблизно досягти ефекту (на основі зображення, яке ви опублікували).
Наступне пояснення не є супер оптимізованою версією, але є концептуально зрозумілим (я сподіваюся). Після того, як ви запустили його, ви зможете оптимізувати його (насправді дуже кардинально).
- Згенеруйте n шарів рівномірного випадкового шуму (просто випадкові пікселі сірого кольору).
- Тепер виберіть кожне з них, відбираючи вибірки кожні 1, 2, 4, 8, ... 2 ^ (n-1) пікселів та інтерполюючи проміжні пікселі. Кожен шар більш гладкий, ніж попередній.
- Тепер масштаб їх з коефіцієнтом 1, 2, 4, 8 і т. Д. Кожен шар темніший за попередній.
- Додайте все це разом.
- Нормалізуйте, розділивши кожен піксель на (1 + 2 + 4 + 8 + ... 2 ^ (n-1)).
Важким кроком є крок вибірки та інтерполяції. Припустимо, ми в шарі пропускаємо вибірку кожного m-го пікселя. Ось основна ідея для m> 1 (якщо m дорівнює 1, ми використовуємо зображення так, як є):
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)
Кілька порад:
- Результат алгоритму вище може здатися трохи вимитим. Ви можете зменшити цей ефект, використовуючи один і той же шар шуму для всіх шарів або згодом покращити контрастність зображення.
- Наведений вище алгоритм використовує лінійну інтерполяцію, але косинусна інтерполяція (пошук) дає набагато кращі результати.
- Дайте можливість дивитися на ваші шари окремо протягом усіх частин алгоритму. Це допоможе вам швидко вимити помилки.