Ответ 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, который может быть полезен здесь.