Я играю с 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);
Результаты нормализованы. Что бы вы использовали, чтобы оказать сильное влияние на развитие шума? Я вижу примеры, когда изменение амплитуды дает мягкие или шероховатые поверхности, но даже если я даю огромную амплитуду, я вижу небольшую разницу.