Лучший способ добавить семена в шум Perlin? - PullRequest
17 голосов
/ 27 августа 2011

Я пытаюсь реализовать 2D генерацию шума Perlin в C ++, и некоторые реализации, которые я нашел, вообще не используют seed ( здесь , здесь или здесь ). Другие реализации принимают начальное значение для получения различного шума в зависимости от значения шума.

Однако я нашел пример кода , где добавили начальное значение к параметрам функции, вычисляющим значение шума для каждой октавы (см. PerlinNoise :: Total () в связанном коде). Другой использует трехмерную начальную функцию и использует фиксированное начальное значение в качестве значения z (не смог найти пример только сейчас). Другие статьи предлагают использовать другие шумовые функции.

Таким образом, мой вопрос заключается в том, как лучше всего добавить начальное значение к генерации шума Perlin. При одинаковом начальном значении должны быть сгенерированы одинаковые значения шума. Если бы решение состояло в том, чтобы иметь пользовательскую функцию шума, мне было бы интересно, если бы она могла быть реализована с использованием Boost.Random (или классов C ++ 11 Standard C ++ Library).

Редактировать: Чтобы ответить на то, что я имею в виду, «лучшим» способом: каков наилучший способ, который дает мне шум Перлина, как будто он должен был работать, например, функция градиентного шума.

1 Ответ

16 голосов
/ 31 августа 2011

Поскольку никто не собирается писать ответ из комментариев, я пробую себя.Пожалуйста, подпишите, когда я прав, прокомментируйте, когда нет:)

Есть несколько реализаций и пример кода, который (пытается) реализовать шум Перлина.Во-первых, существует реализация улучшенного эталонного шума от самого Кена Перлина.

Случай 1: улучшенная эталонная реализация шумов

Функция шума принимает три двойных значения и выводит значение,При создании двумерного растрового изображения с использованием x и y и сохранении постоянной z получается хорошо известная схема шума Перлина.Когда z изменяется от 0,0 до 1,0, шумовые облака, кажется, медленно «меняются».Таким образом, метод заполнения, который устанавливает z, например, z = 10.0 * seed, может работать для "заполнения".

Еще один способ заполнения функции шума заключается в следующем: если вы всегда просто получаете шум в диапазоне [0.0;64.0 [для x и y, можно инициировать шум путем добавления смещения к x, y или обоим при вызове функции шума: noise (x + 64.0 * seed, y + 64.0 * seed).

Case2: Стиль учебника Код шума Perlin

Затем есть реализация шума Perlin *1016* (адаптированная и использованная во многих других учебниках по шуму Perlin), которая имеет функцию базового шума, такую ​​как (псевдокод):

function Noise2(integer x, integer y)
    n = x + y * 57
    n = (n<<13) ^ n;
    return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589)
       & 7fffffff) / 1073741824.0);    
end function

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

Решение добавить начальное число к этому типу реализации шума Перлина состоит в том, чтобы написать функцию, которая равномерно распределяет выходные значения для заданных значений x и y (и путем возвратаодно и то же значение для одинаковых значений x и y, конечно).Эта функция может быть написана с использованием Boost.Random (код не проверен):

double Noise2(int x, int y)
{
   uint32_t seeds[3] = { uint32_t(x), uint32_t(y), seed };
   boost::mt19937 rng(seeds, seeds+3);
   boost::uniform_real<> dist(0.0, 1.0);
   boost::variate_generator<boost::mt19937&, boost::uniform_real<> >
      die(rng, dist);
   return die();
}

Генератор случайных чисел имеет несколько ctors, среди которых один, который принимает диапазон uint32_t, которые определяют начальное состояние RNG.

Есть также библиотеки, которые генерируют когерентный шум, такие как libnoise , которые могут быть здесь полезны.

Симплексный шум

Я не сделалспросите о симплексном шуме, но одна реализация (от Стефана Густавсона) , которую я обнаружил, использует похожую технику (некоторые предварительно вычисленные таблицы), как эталонная реализация Кена Перлина, и может быть засеяна так же, как и в случае 1 выше.Комментатор Робинсон упомянул посев при создании справочной таблицы, но я не знаю, как это будет работать.

...