Я пытаюсь реализовать Perlin Noise в C++.Алгоритм Perlin Noise, похоже, не создает градиентный шум
Во-первых, проблема (я думаю) заключается в том, что выход не является тем, что я ожидаю. В настоящее время я просто использовать сгенерированные значения шума Перлина в полутоновых изображениях, и это результаты, которые я получаю:
Однако, от моего понимания, это должно выглядеть более вдоль линий:
То есть шум, который я производю в настоящее время, по-видимому, больше связан с «стандартными» нерегулярными шумами.
Это Перлин шум алгоритм я реализовал до сих пор:
float perlinNoise2D(float x, float y)
{
// Find grid cell coordinates
int x0 = (x > 0.0f ? static_cast<int>(x) : (static_cast<int>(x) - 1));
int x1 = x0 + 1;
int y0 = (y > 0.0f ? static_cast<int>(y) : (static_cast<int>(y) - 1));
int y1 = y0 + 1;
float s = calculateInfluence(x0, y0, x, y);
float t = calculateInfluence(x1, y0, x, y);
float u = calculateInfluence(x0, y1, x, y);
float v = calculateInfluence(x1, y1, x, y);
// Local position in the grid cell
float localPosX = 3 * ((x - (float)x0) * (x - (float)x0)) - 2 * ((x - (float)x0) * (x - (float)x0) * (x - (float)x0));
float localPosY = 3 * ((y - (float)y0) * (y - (float)y0)) - 2 * ((y - (float)y0) * (y - (float)y0) * (y - (float)y0));
float a = s + localPosX * (t - s);
float b = u + localPosX * (v - u);
return lerp(a, b, localPosY);
}
Функция calculateInfluence имеет работу генерации случайного вектора градиента и вектор расстояния для одного из угловых точек текущей сетки ячейку и возвращать точечный продукт из них. Он реализован в виде:
float calculateInfluence(int xGrid, int yGrid, float x, float y)
{
// Calculate gradient vector
float gradientXComponent = dist(rdEngine);
float gradientYComponent = dist(rdEngine);
// Normalize gradient vector
float magnitude = sqrt(pow(gradientXComponent, 2) + pow(gradientYComponent, 2));
gradientXComponent = gradientXComponent/magnitude;
gradientYComponent = gradientYComponent/magnitude;
magnitude = sqrt(pow(gradientXComponent, 2) + pow(gradientYComponent, 2));
// Calculate distance vectors
float dx = x - (float)xGrid;
float dy = y - (float)yGrid;
// Compute dot product
return (dx * gradientXComponent + dy * gradientYComponent);
}
Здесь расстояние представляет собой генератор случайных чисел из C++ 11:
std::mt19937 rdEngine(1);
std::normal_distribution<float> dist(0.0f, 1.0f);
И лерп просто реализован как:
float lerp(float v0, float v1, float t)
{
return (1.0f - t) * v0 + t * v1;
}
Для реализации алгоритма я в основном использовал следующие два ресурса:
Perlin Noise FAQ Perlin Noise Pseudo Code
Это трудно для меня, чтобы точно определить, где я, кажется, Мессинг. Может быть, я неправильно генерирую векторы градиента, так как я не совсем уверен, какой тип распределения они должны иметь. Я пробовал с равномерным распределением, однако, похоже, это создавало повторяющиеся шаблоны в текстуре!
Также может быть, что я неправильно усредняю значения влияния. Было немного сложно понять, как это должно быть сделано из статьи часто задаваемых вопросов о шуме Perlin.
Есть ли у кого-нибудь какие-либо намеки относительно того, что может быть неправильным с кодом? :)
Aha! Проблема с использованием октав, казалось, была проблемой :) Я получаю гораздо лучшие результаты сейчас! – CodingBeagle
Невероятно, у меня также была эта проблема совсем недавно! – Dave3of5