C++ 柏林噪声算法似乎不会产生梯度噪声

C++ 柏林噪声算法似乎不会产生梯度噪声,c++,algorithm,random,noise,perlin-noise,C++,Algorithm,Random,Noise,Perlin Noise,我试图在C++中实现Perlin Noise。< /P> 首先,问题是(我认为)输出不是我所期望的。目前我只是在灰度图像中使用生成的柏林噪声值,我得到的结果如下: 然而,根据我的理解,应该更多地关注以下方面: 也就是说,我目前产生的噪音似乎更接近“标准”不规则噪音 这是我迄今为止实施的柏林噪声算法: float perlinNoise2D(float x, float y) { // Find grid cell coordinates int x0 = (x > 0.

我试图在C++中实现Perlin Noise。< /P> 首先,问题是(我认为)输出不是我所期望的。目前我只是在灰度图像中使用生成的柏林噪声值,我得到的结果如下:

然而,根据我的理解,应该更多地关注以下方面:

也就是说,我目前产生的噪音似乎更接近“标准”不规则噪音

这是我迄今为止实施的柏林噪声算法:

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);
}
这里,dist是C++11中的一个随机数生成器:

std::mt19937 rdEngine(1);
std::normal_distribution<float> dist(0.0f, 1.0f);
为了实现该算法,我主要使用了以下两种资源:

我很难准确地指出我到底把事情搞砸了。这可能是因为我生成的梯度向量不正确,因为我不太确定它们应该有什么类型的分布。我尝试过均匀分布,但这似乎会在纹理中生成重复图案

同样,可能是我对影响值的平均值不正确。从柏林噪声常见问题解答文章中,我们很难确切地看出应该如何做到这一点


有人对代码可能有什么问题有任何提示吗?:)

你似乎只产生了一个八度的柏林噪声。要获得如图所示的结果,需要生成并将它们相加。在一系列八度音阶中,每个八度音阶的网格单元大小应该是上一个八度音阶的两倍

要生成多倍频程噪声,请使用类似的方法:

float multiOctavePerlinNoise2D(float x, float y, int octaves)
{
    float v = 0.0f;
    float scale = 1.0f;
    float weight = 1.0f;
    float weightTotal = 0.0f;
    for(int i = 0; i < octaves; i++)
    {
        v += perlinNoise2D(x * scale, y * scale) * weight;
        weightTotal += weight;
        // "ever-increasing frequencies and ever-decreasing amplitudes"
        // (or conversely decreasing freqs and increasing amplitudes)
        scale *= 0.5f; 
        weight *= 2.0f;
    }
    return v / weightTotal;
}
float multiOctavePerlinNoise2D(float x,float y,int-octave)
{
浮球v=0.0f;
浮动刻度=1.0f;
浮子重量=1.0f;
浮球重量总和=0.0f;
对于(int i=0;i<八度;i++)
{
v+=perlinNoise2D(x*刻度,y*刻度)*重量;
总重量+=重量;
//“不断增加的频率和不断减少的振幅”
//(或相反地降低频率和增加振幅)
刻度*=0.5f;
重量*=2.0f;
}
返回v/weightTotal;
}
对于额外的随机性,您可以为每个倍频程使用不同种子的随机生成器。此外,每个倍频程的权重可以改变,以调整噪声的美学质量。如果在每次迭代中未调整权重变量,则上面的示例为(频率的每次倍增携带相同的权重)


此外,您还需要使用一个随机数生成器,该生成器每次为给定的xGrid、yGrid对返回相同的值。

Aha!不使用八度音阶似乎是个问题:)我现在得到了更好的效果!难以置信,我最近也有这个问题!
float lerp(float v0, float v1, float t)
{
    return ( 1.0f - t ) * v0 + t * v1;
}
float multiOctavePerlinNoise2D(float x, float y, int octaves)
{
    float v = 0.0f;
    float scale = 1.0f;
    float weight = 1.0f;
    float weightTotal = 0.0f;
    for(int i = 0; i < octaves; i++)
    {
        v += perlinNoise2D(x * scale, y * scale) * weight;
        weightTotal += weight;
        // "ever-increasing frequencies and ever-decreasing amplitudes"
        // (or conversely decreasing freqs and increasing amplitudes)
        scale *= 0.5f; 
        weight *= 2.0f;
    }
    return v / weightTotal;
}