Я играю с Perlin Noise после некоторой работы с Diamond Square. Я следил за реализацией Хьюго Элиаса, которая в основном создает серию функций с x, y в качестве входных данных для выдачи каждого значения координаты.
Мой код PHP здесь :
У меня есть два вопроса:
Как использовать алгоритм для генерации карты высот в массиве? Я не совсем понял это и просто портировал на PHP псевдокод, но выполнил последнюю функцию (map_perlined) после прочтения где-то, что алгоритм «волшебным образом» дает вам переходные значения для каждой заданной точки x, y (очевидно, без необходимости читать ее смежные значения), я просто получаю это при использовании в качестве случайной функцииmt_rand(-100,100)/100;
И это при использовании криптографии: 1.0-(($n*($n*$n*15731+789221)+1376312589)&0x7fffffff)/1073741824.0;
(что, кстати, может быть реализовано «как есть» в PHP?):
Итак, подводим итоги, три вопроса:
- Мой код правильный?
- Случайная функция может быть перенесена в PHP, как описано в коде? Не выдает ошибок, но результатов нет.
- Как мне на самом деле использовать алгоритм?
ОБНОВИТЬ
Хорошо, сделал порт PHP из кода, показанного в статье Густавсона, и, как сказал другой кодер, он просто генерирует одну октаву. Есть какой-нибудь другой полезный сайт / бумага / руководство о том, как использовать это с понятиями нескольких октав, амплитуды, частоты и т. Д. Для управления функцией шума? На бумаге Густавсона просто показаны результаты, а не фактическая реализация алгоритма, возможно, я что-то упустил?
ОБНОВЛЕНИЕ 2
@NATHAN
Я сделал что-то вроде:
$persistence = 0.5;
for ($j = 0; $j < $size; $j++) {
for ($i = 0; $i < $size; $i++) {
for ($o = 0; $o < 8; $o++) {
$frequency = pow(2,$o);
$amplitude = pow($persistence, $o);
$value += SimplexNoise($i*$frequency, $j * $frequency) * $amplitude;
}
//$value = SimplexNoise($i, $j) + 0.5 * SimplexNoise($i, $j) + 0.25 * SimplexNoise($i, $j);
$this->mapArray[$i][$j] = new Cell($value);
И после нормализации значений до 0..1 я получаю довольно скучную карту высот, такую как:
Как мне посеять карту? Возможно, что мне нужно реализовать, это 3d-версия с третьим значением случайной высоты? Но если это так, я должен был бы принять во внимание соседние значения, которые я бы закончил чем-то вроде алгоритма алмазного квадрата, именно то, что я не хочу делать.
ОБНОВЛЕНИЕ 3
Больше работы Перлина. Я еще не нашел способ, чтобы направить шум к моим результатам. Проверьте эти октавы и конечный результат:
Октава I в IV
Подвела
Каждая октава почти одинакова. Проверьте код:
$persistence = 0.5;
for ($j = 0; $j < $size; $j++) {
for ($i = 0; $i < $size; $i++) {
$value = 0;
for ($o = 0; $o < 4; $o++) {
$frequency = pow(2,$o);
$amplitude = pow($persistence, $o);
$value += improved_noise($i*$frequency, $j*$frequency, 0.5)*$amplitude;
}
$this->map[$i][$j] = new Cell($value);
Результаты нормализованы. Что бы вы использовали, чтобы оказать сильное влияние на развитие шума? Я вижу примеры, когда изменение амплитуды дает мягкие или шероховатые поверхности, но даже если я даю огромную амплитуду, я вижу небольшую разницу.
Ответы:
То, что вы реализовали, - это не шум Перлина. Я не уверен, почему Хьюго Элиас так говорит, но он в замешательстве. Вот эталонная реализация Кена Перлина. На самом деле он не вызывает никакого внешнего генератора случайных чисел, но использует встроенную хеш-функцию для получения псевдослучайных векторов градиента.
Также обратите внимание, что шум Перлина состоит только из одной октавы. Суммирование нескольких октав (масштабированных экземпляров шумовой функции), как предполагает Хьюго Элиас, является полезной техникой, но не частью шума Перлина. То, что вы получаете, это называется фрактальным шумом, иногда «фрактальным броуновским шумом» (из-за предполагаемого сходства с броуновским движением).
Если вы хотите геометрически понять, что делает алгоритм, попробуйте эту статью . Речь идет о другом типе шума, называемом «симплексный шум», но также включает в себя объяснение классического шума Перлина. Кстати, симплексный шум был также изобретен Перлином и, как предполагается, является улучшением по сравнению с его классическим шумом, так что вы можете попробовать реализовать его также, если вам интересно поиграть с шумовыми функциями.
источник
Это распространенное заблуждение. То, что Уго Элиас называет "шумом Перлина", на самом деле является фрактальным, или розовым, шумом. Чтобы лучше понять, что такое шум Perlin, вы можете прочитать статью Perlin, связанную в ответе Натана Рида, или документы libnoise (там та же ошибка: шум Perlin - это то, что они называют градиентным шумом), или документы CoherentNoise .
Теперь, чтобы действительно ответить на ваш вопрос: вы не получили ожидаемый результат, потому что частота шума слишком высока. Ваши частоты начинаются с 1 и увеличиваются, что означает, что каждый пиксель в получающейся карте имеет случайное значение. Чтобы увидеть более тонкую структуру карты, вам нужно «увеличить» шум. Я действительно не говорю на PHP, но я полагаю, что код должен выглядеть следующим образом:
То есть вы «растягиваете» один период шума по всей вашей карте. Конечно, вы можете использовать другие коэффициенты - просто попробуйте другие, посмотрите, что получится.
источник