WebGL должен быть включен. На момент написания этой статьи я рекомендовал использовать Chrome для лучшей производительности.

аюсь реализовать какой-то исходный код, который я нашелонлайн чтобы создать карту высот, используя Perlin Noise. Мне успешно удалось получить карту высот, используя функцию noise3, где третья координата была случайным «семенем», чтобы учесть случайные карты высот.

Моя проблема в том, что созданный ландшафт довольно скучный - я хочу горы, и я получаю пологий луг. Я немного читал о Perlin Noise (в основномВот). Из-за исходного кода, который я обнаружил явно не написанным для удобства чтения, и из-за моего слабого понимания концепции Perlin Noise в целом, я не могу понять, что мне нужно настроить в коде (амплитуду и частоту?), Чтобы создать более резкую местность.

Также будет приветствоваться дополнительная информация о создании карт высот с использованием Perlin Noise, Perlin Noise в целом или даже более расшифрованного кода.

РЕДАКТИРОВАТЬ: Я понимаю (вроде), как работает Perlin Noise, например, в отношении амплитуды и частоты, мне просто интересно, какие переменные нужно изменить в коде, который я связал выше, которые используются для этих двух аспектов.

 bobobobo22 дек. 2012 г., 15:21
Обычный шум Перлина («1 слой шума») скучен. То, что вы ищете, обычно называют «фрактальным броуновским шумом движения» (fBm), где вы добавляете шум Перлина разных частот вместе. Видетьздесь для больших определений лакунарности, частоты, октавы Wrt Perlin фрактальный шум
 LarsH10 янв. 2017 г., 12:28
Для тех, кто придет сюда: концепции, которые Эрик пытался реализовать на основе статьи Элиаса, на самом деле являются не шумом Перлина, а ценным шумом, слоистым в фрактальный (розовый) шум.

Ответы на вопрос(4)

насколько высокая / низкая местность, частота, как она течет, а более низкая частота - больше.

Так что если вы хотите неровный горный пейзаж, вам нужно поднять оба.

 SinisterRainbow02 дек. 2012 г., 00:57
Он может захотеть, чтобы начались приблизительные цифры - если так: 2-6 для частоты, подходящей для небольших ландшафтов, октавы 1-16 в порядке, усилитель - просто нормализованное поле. Я генерирую город и выбираю здания на его основе для сетки 32x32, и нахожу, что эти диапазоны хороши ... Freq 5+ дает мне лучшие результаты в том, что я делаю.
Решение Вопроса

которые вы устанавливаете, то есть амплитудой, частотой и устойчивостью. Количество октав немного изменилось, но не сильно. В коде, который я написал в прошлом, я просто играл с порядком величины частоты и стойкости, пока не получил то, что мне было нужно. Я могу попытаться найти свой старый источник, если это необходимо.

PerlinNoise.h
#pragma once

class PerlinNoise
{
public:

  // Constructor
    PerlinNoise();
    PerlinNoise(double _persistence, double _frequency, double _amplitude, int _octaves, int _randomseed);

  // Get Height
    double GetHeight(double x, double y) const;

  // Get
  double Persistence() const { return persistence; }
  double Frequency()   const { return frequency;   }
  double Amplitude()   const { return amplitude;   }
  int    Octaves()     const { return octaves;     }
  int    RandomSeed()  const { return randomseed;  }

  // Set
  void Set(double _persistence, double _frequency, double _amplitude, int _octaves, int _randomseed);

  void SetPersistence(double _persistence) { persistence = _persistence; }
  void SetFrequency(  double _frequency)   { frequency = _frequency;     }
  void SetAmplitude(  double _amplitude)   { amplitude = _amplitude;     }
  void SetOctaves(    int    _octaves)     { octaves = _octaves;         }
  void SetRandomSeed( int    _randomseed)  { randomseed = _randomseed;   }

private:

    double Total(double i, double j) const;
    double GetValue(double x, double y) const;
    double Interpolate(double x, double y, double a) const;
    double Noise(int x, int y) const;

    double persistence, frequency, amplitude;
    int octaves, randomseed;
};
PerlinNoise.cpp
#include "PerlinNoise.h"

PerlinNoise::PerlinNoise()
{
  persistence = 0;
  frequency = 0;
  amplitude  = 0;
  octaves ,= 0;
  randomseed = 0;
}

PerlinNoise::PerlinNoise(double _persistence, double _frequency, double _amplitude, int _octaves, int _randomseed)
{
  persistence = _persistence;
  frequency = _frequency;
  amplitude  = _amplitude;
  octaves = _octaves;
  randomseed = 2 + _randomseed * _randomseed;
}

void PerlinNoise::Set(double _persistence, double _frequency, double _amplitude, int _octaves, int _randomseed)
{
  persistence = _persistence;
  frequency = _frequency;
  amplitude  = _amplitude;
  octaves = _octaves;
  randomseed = 2 + _randomseed * _randomseed;
}

double PerlinNoise::GetHeight(double x, double y) const
{
  return amplitude * Total(x, y);
}

double PerlinNoise::Total(double i, double j) const
{
    //properties of one octave (changing each loop)
    double t = 0.0f;
    double _amplitude = 1;
    double freq = frequency;

    for(int k = 0; k < octaves; k++) 
    {
        t += GetValue(j * freq + randomseed, i * freq + randomseed) * _amplitude;
        _amplitude *= persistence;
        freq *= 2;
    }

    return t;
}

double PerlinNoise::GetValue(double x, double y) const
{
    int Xint = (int)x;
    int Yint = (int)y;
    double Xfrac = x - Xint;
    double Yfrac = y - Yint;

  //noise values
  double n01 = Noise(Xint-1, Yint-1);
  double n02 = Noise(Xint+1, Yint-1);
  double n03 = Noise(Xint-1, Yint+1);
  double n04 = Noise(Xint+1, Yint+1);
  double n05 = Noise(Xint-1, Yint);
  double n06 = Noise(Xint+1, Yint);
  double n07 = Noise(Xint, Yint-1);
  double n08 = Noise(Xint, Yint+1);
  double n09 = Noise(Xint, Yint);

  double n12 = Noise(Xint+2, Yint-1);
  double n14 = Noise(Xint+2, Yint+1);
  double n16 = Noise(Xint+2, Yint);

  double n23 = Noise(Xint-1, Yint+2);
  double n24 = Noise(Xint+1, Yint+2);
  double n28 = Noise(Xint, Yint+2);

  double n34 = Noise(Xint+2, Yint+2);

    //find the noise values of the four corners
    double x0y0 = 0.0625*(n01+n02+n03+n04) + 0.125*(n05+n06+n07+n08) + 0.25*(n09);  
    double x1y0 = 0.0625*(n07+n12+n08+n14) + 0.125*(n09+n16+n02+n04) + 0.25*(n06);  
    double x0y1 = 0.0625*(n05+n06+n23+n24) + 0.125*(n03+n04+n09+n28) + 0.25*(n08);  
    double x1y1 = 0.0625*(n09+n16+n28+n34) + 0.125*(n08+n14+n06+n24) + 0.25*(n04);  

    //interpolate between those values according to the x and y fractions
    double v1 = Interpolate(x0y0, x1y0, Xfrac); //interpolate in x direction (y)
    double v2 = Interpolate(x0y1, x1y1, Xfrac); //interpolate in x direction (y+1)
    double fin = Interpolate(v1, v2, Yfrac);  //interpolate in y direction

    return fin;
}

double PerlinNoise::Interpolate(double x, double y, double a) const
{
    double negA = 1.0 - a;
  double negASqr = negA * negA;
    double fac1 = 3.0 * (negASqr) - 2.0 * (negASqr * negA);
  double aSqr = a * a;
    double fac2 = 3.0 * aSqr - 2.0 * (aSqr * a);

    return x * fac1 + y * fac2; //add the weighted factors
}

double PerlinNoise::Noise(int x, int y) const
{
    int n = x + y * 57;
    n = (n << 13) ^ n;
  int t = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff;
    return 1.0 - double(t) * 0.931322574615478515625e-9;/// 1073741824.0);
}
 LarsH10 янв. 2017 г., 12:31
Просто для записи, несмотря на название, приведенный здесь код является реализациейстоимость шум, наслоенный нафрактальный шум. этоне Шум Перлина, который является типом градиентного шума (en.wikipedia.org/wiki/Gradient_noise).
 Nick Banks10 авг. 2011 г., 05:46
Конечно. Делай что хочешь с кодом.

и я подумал, что попытаюсь прояснить пару вещей, которые не рассматриваются в принятом ответе.

Интересная и полезная статья Элиаса использует «значение шума», а не «шум Перлина». Значение шума включает в себя подгонку кривой случайных точек. Градиентный шум (основным примером которого является шум Перлина) создает решетку из точек с 0 значениями и дает каждому случайный градиент. Их часто путают друг с другом!

http://en.wikipedia.org/wiki/Gradient_noise

Во-вторых, использование 3-го значения в качестве семени дорого. Если вы хотите случайный рельеф, вместо этого рассмотрите перевод случайного количества вашего происхождения. 3D-звонки будут стоить дороже, чем 2D-звонки. И все, что вы делаете, это используете значение z, чтобы выбрать определенный фрагмент 2D-шума.

В-третьих, прямой вызов функции будет возвращать значения, которые являются достаточно плавными и в целом скользящими, не такими грубыми, как реальная местность, поскольку ее случайность ограничена одной частотой. Чтобы получить более сложный рельеф, хорошей техникой является суммирование нескольких вызовов, проходящих через шумовое пространство на разных частотах, обычно устанавливающих «фрактальные» значения.

Таким образом, например, сумма вместеnoise(x, y) + (1/2)(noise(x*2, y*2) + (1/4)(noise(x*4, y*4)...

Результирующая сумма, вероятно, часто будет выходить за пределы диапазона от -1 до 1, поэтому вам придется нормализовать результат, прежде чем значения будут полезны. Я хотел бы предложить установить ряд факторов (1, 1/2, 1/4 и т. Д.), Чтобы вы гарантированно оставались в пределах [-1, 1], что может быть достигнуто путем прогрессивного взвешивания в зависимости от того, сколько «октавы» вы используете. (Но я не знаю, действительно ли это самый эффективный способ сделать это.)

Пример с четырьмя октавами:(1/15)(noise(x, y) + (2/15)(noise(2x, 2y) + (4/15)(noise(4x, 4y) + (8/15)(noise(8x, 8y)

Затем используйте нормализацию "турбулентного шума", взяв сумму и сделав ее= |sum| (т. е. используя функцию abs). Это даст рельефу местности определенные угловые гребни долины, в отличие от плавного вращения.

Я работаю над визуализатором SimplexNoise, надеюсь, в конце концов, я открою его на GitHub как проект Java. Первый черновик визуализатора можно найти и запустить через этот пост на java-gaming.org:http://www.java-gaming.org/topics/simplex-noise-experiments-towards-procedural-generation/27163/view.html Акцент на первом проекте более учебный, с примерами сгенерированного кода (но они на Java).

Отличная статья о том, как SimplexNoise работает (и Perlin vs Gradient background):http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf

Стефан Густавсон проделал отличную работу!

 Phil Freihofner02 мар. 2015 г., 20:00
Визуализатор, о котором я упоминал выше, находится по адресу github.com/philfrei/SiVi. Хотелось бы, чтобы некоторые люди помогли добавить новые функции, если есть интерес.

которую я написал недавно в JavaScript с использованием 3D Perlin Noise. Поскольку на поверхности присутствуют воксели или нет, я просто применяю порог после вычисления куба Perlin Noise. В этом примере вероятность шума одинакова для всех измерений. Вы можете получить более реалистичный пейзаж, увеличивая случайные значения до уровня земли и уменьшая его до уровня неба.

http://kirox.de/test/Surface.html

WebGL должен быть включен. На момент написания этой статьи я рекомендовал использовать Chrome для лучшей производительности.

Ваш ответ на вопрос