Если вы все еще читаете это на носителе, я переместил свой блог на http://yvanscher.com/blog.html

Я не видел тонны отличных примеров создания карт с шумом Перлина на Python. Итак, поехали!

Шум Перлина - это математическая формула, используемая для создания «реалистичных» структур. Это шум, но в отличие от обычного шума он имеет некоторую когерентную структуру. Вот сравнение обычного шума и шума Перлина:

В модуле python noise есть несколько параметров, которые влияют на то, что вы видите, когда генерируете свой шум Perlin:

  1. масштаб: число, определяющее, на каком расстоянии просматривать карту шума.
  2. октавы: количество уровней детализации, которое вы хотите, чтобы ваш шум Перлина имел.
  3. лакунарность: число, определяющее, сколько деталей добавляется или удаляется в каждой октаве (регулирует частоту).
  4. стойкость: число, определяющее, насколько каждая октава влияет на общую форму (регулирует амплитуду).

Мы не будем слишком беспокоиться о масштабе, вы можете использовать его для уменьшения (больший масштаб) или увеличения (меньший масштаб).

Шум Перлина сочетает в себе несколько функций, называемых «октавами», для создания естественных поверхностей. Каждая октава добавляет детали к поверхности. Например: октава 1 может быть горами, октава 2 может быть валунами, октава 3 может быть скалами.

Лакунарность более 1 означает, что каждая октава будет повышать уровень детализации (повышенная частота). Лакунарность 1 означает, что каждая октава будет иметь уровень детализации сэма. Лакунарность меньше единицы означает, что каждая октава станет более плавной. Последние два обычно нежелательны, поэтому лакунарность 2 работает вполне нормально.

Последовательность определяет, насколько каждая октава вносит вклад в общую структуру карты шума. Если ваша настойчивость равна 1, все октавы вносят равный вклад. Если ваша настойчивость больше 1, последовательные октавы вносят больший вклад и вы получаете что-то более близкое к обычному шуму (спойлер, изображение обычного шума выше на самом деле является шумом Перлина с присутствием 5,0). Установкой по умолчанию было бы сопротивление менее 1.0, что уменьшит эффект более поздних октав.

Хотя, хватит болтать! Давайте проведем несколько экспериментов. Сначала давайте начнем с шума Перлина по умолчанию и сопровождающего его изображения:

В нашем скрипте этот шум Перлина выглядит как двумерный массив значений от -1 до 1. Значения, которые темнее на карте, имеют более низкие значения, значения, близкие к 1, светлее. Далее я хочу попробовать присвоить два цвета разным диапазонам значений на этой карте, чтобы создать рельеф:

Эта карта местности довольно аккуратная; здесь неровные берега, пляжи и много воды. хотя я никогда не наблюдал такой естественный рельеф, если мы посмотрим на любую часть карты, он покажется «реалистичным». Давайте сделаем еще один шаг и добавим горы и снег:

Это круто, но этот рисунок местности явно неестественный. Чтобы сделать его более естественным, мы будем использовать круговой фильтр, чтобы избавиться от всего преиферического шума Перлина:

Здесь я пытался создать остров, поэтому я сделал круговой фильтр, а затем применил его к массиву шума perlin color_world. В итоге я оказался планетой, плавающей в океане. Я изменил цвет океана на черный, и это выглядит довольно круто! Тем не менее, я хотел остров, так что давайте попробуем еще раз. На этот раз мы рассчитаем круговой градиент, а затем применим его к шуму Перлина в качестве фильтра.

Круговой градиент:

Я много боролся с этой частью. Я уверен, что есть более эффективный способ получить такой градиент, но я придумал то, что описано выше. Я рассчитал метрику расстояния от центра карты, а затем нормализовал, сжал и переномментировал эти расстояния, чтобы получить этот сферический градиент. Снова светлее означает, что значение ближе к 1, более темные цвета ближе к 0. Затем я применяю этот круговой градиент к шуму Перлина, который мы создали ранее.

Круговой градиент + шум:

Эта часть была менее сложной, но все же болезненной. Я умножаю шум Перлина на градиент круга, а затем увеличиваю контраст, умножая положительные (более светлые значения) на 20. Затем я перенормирую, чтобы снова сделать его 0–1.

Раскрашенный круговой градиент + шум:

Это действительно здорово, и похоже, что архипелаг намного более естественный. Я рекомендую вам попробовать разные методы затенения и, возможно, случайно удалить некоторые участки. Я собираюсь изменить пороговое значение и установить его как threshold = 0.2. В результате получится меньший, но более реалистичный архипелаг:

Вот и мы! У нас есть островной архипелаг с естественным видом! Итак, теперь, когда у нас есть наши острова, вы можете заметить, что независимо от того, как часто вы перезапускаете этот скрипт, шум перлина будет создавать одни и те же острова. Чтобы получить новые острова, вы можете установить параметр base функции pnoise2 на случайное целое число, давайте попробуем base=5, base=100:

Заключение

Итак, мы начали с простого шума и в итоге пришли к способу создания действительно неограниченного количества уникальных и естественных архипелагов! Надеюсь, вам понравился этот пост!

Полный блокнот со всем кодом здесь.

Если вам понравился этот пост, вы можете подписаться на мою рассылку здесь и быть в курсе крутых и интересных проектов.