РЕДАКТИРОВАТЬ: В итоге я использовал библиотеку FastNoise, найденную здесь: https://github.com/Auburns/FastNoise В нем есть все под солнцем, что может понадобиться кому-то для создания различных шумов. Судя по названию, это тоже довольно быстро!
Я создаю двумерный бесконечно процедурно сгенерированный мир. Я загружаю и выгружаю куски с диска по мере движения игрока. Я использую функцию клеточного автомата, чтобы определить, как создаются локальные плитки в каждом фрагменте, но мне нужен шум (в данном случае Perlin), чтобы определить, к какому типу биома будет относиться каждый фрагмент при создании новых. Я понимаю, как я бы перевел десятичные дроби между 0 и 1, чтобы представить это, моя единственная проблема заключается в том, что в учебнике, которому я следовал по созданию шума Перлина, требуется, чтобы вы передали ему предопределенный 2-мерный массив и вернули массив шума того же размера. Поскольку мой мир динамично растет, я немного запутался в том, как использовать массив фиксированного размера для обозначения новых типов блоков.
Другие ответы, которые я видел, не охватывают точно, как справиться с бесконечной частью генерации шума. Мое лучшее предположение состоит в том, что мне нужно каким-то образом генерировать или расширять шум с каждым вновь созданным фрагментом, хотя то, как я это делаю, меня озадачивает.
Вот код, который я перевел отсюда на C #: http://devmag.org.za/2009/04/25/perlin-noise/
по общему признанию, часть математики здесь я еще не совсем понимаю, особенно поразрядная функция!
public class PerlinNoiseGenerator
{
public int OctaveCount { get; set; }
public float Persistence { get; set; }
public PerlinNoiseGenerator(int octaveCount, float persistence)
{
this.OctaveCount = octaveCount;
this.Persistence = persistence;
}
public float[,] GenerateWhiteNoise(int width, int height)
{
float[,] noiseFieldToReturn = new float[width, height];
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
noiseFieldToReturn[i, j] = (float)Game1.Utility.RGenerator.NextDouble() % 1;
}
}
return noiseFieldToReturn;
}
public float[,] SmoothNoiseField(float[,] whiteNoise, int octave)
{
int width = whiteNoise.GetLength(0);
int height = whiteNoise.GetLength(1);
float[,] smoothField = new float[width, height];
int samplePeriod = 1 << octave;
float sampleFrequency = 1.0f / samplePeriod;
for(int i =0; i < width; i++)
{
int samplei0 = (i / samplePeriod) * samplePeriod;
int samplei1 = (samplei0 + samplePeriod) % width;
float horizontalBlend = (i - samplei0) * sampleFrequency;
for(int j =0; j < height; j++)
{
int samplej0 = (j/samplePeriod) * samplePeriod;
int samplej1 = (samplej0 + samplePeriod) % height;
float verticalBlend = (j - samplej0) * sampleFrequency;
float top = LinearInterpolate(whiteNoise[samplei0, samplej0],
whiteNoise[samplei1, samplej0], horizontalBlend);
float bottom = LinearInterpolate(whiteNoise[samplei0, samplej1],
whiteNoise[samplei1, samplej1], horizontalBlend);
smoothField[i, j] = LinearInterpolate(top, bottom, verticalBlend);
}
}
return smoothField;
}
public float[,] GeneratePerlinNoise(float[,] baseNoise, int octaveCount)
{
int width = baseNoise.GetLength(0);
int height = baseNoise.GetLength(1);
float[][,] smoothNoise = new float[octaveCount][,];
float persistance = .5f;
for(int i =0; i < octaveCount;i++)
{
smoothNoise[i] = SmoothNoiseField(baseNoise, i);
}
float[,] perlinNoise = new float[width, height];
float amplitude = 1f;
float totalAmplitude = 0.0f;
for(int octave = octaveCount - 1; octave > 0; octave-- )
{
amplitude *= persistance;
totalAmplitude += amplitude;
for(int i =0; i < width;i++)
{
for(int j =0; j < height; j++)
{
perlinNoise[i, j] += smoothNoise[octave][i, j] * amplitude;
}
}
}
for(int i =0; i < width; i++)
{
for(int j =0; j < height; j++)
{
perlinNoise[i, j] /= totalAmplitude;
}
}
return perlinNoise;
}
public float LinearInterpolate(float a, float b, float alpha)
{
return a * (1 - alpha) + alpha * b;
}
}
Этот код должен компилироваться и генерировать массив шума ФИКСИРОВАННОГО размера.
perlinNoise[i, j] and width, height
. У меня нет времени помогать тебе больше, чем это. - person Christophe Roussy   schedule 07.10.2019