Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Функция шума принимает три двойных значения и выводит значение. При создании 2D-растрового изображения с использованием x и y и постоянном z, вы получаете хорошо известный шаблон шума Perlin. Когда 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

Затем существует реализация шума 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, который определяет начальное состояние RNG.

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

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

Я не спрашивал о симплекс-шуме, но реализация