Лучший способ добавить семя к шуму Perlin?

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

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

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

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

1 ответов


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

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

Случай 1: улучшенная реализация ссылки на шум

функция шума принимает 3 двойных значения и выводит наружу а значение. При создании 2D-растрового изображения с использованием x и y и сохранении постоянной z получается хорошо известная картина шума Перлина. Когда z изменяется между 0.0 и 1.0, шумовые облака, похоже, "меняются" медленно. Итак, метод посева, который устанавливает z, например z = 10.0 * seed, может работать для "посева".

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

случай 2: стиль учебника Perlin noise code

то есть реализация шума Perlin (адаптирован и используется во многих других учебниках шума 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

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

решение для добавления семени к этому типу реализации шума Perlin-написать функцию, которая равномерно распределяет выходные значения для заданных значений 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, которые определяют начальное состояние ГСЧ.

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

Симплекс Шума

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