Perlin噪声2D:将静态转换为云

3

我正在努力理解Perlin噪声。

这篇文章对我有所帮助,我一直在尝试重新创建它提供的云类型图像。

我的噪声代码如下:

#include "terrain_generator.hpp"

using namespace std;


#define PI 3.1415927;

float noise(int x, int y)
{
    int n = x + y * 57;
    n = (n<<13) ^ n;
    return (1.0 - ( (n * ((n * n * 15731) + 789221) +  1376312589) & 0x7fffffff) / 1073741824.0);
}

float cosine_interpolate(float a, float b, float x)
{
    float ft = x * PI;
    float f = (1 - cos(ft)) * 0.5;
    float result =  a*(1-f) + b*f;
    return result;
}

float smooth_noise_2D(float x, float y)
{  
    float corners = ( noise(x-1, y-1)+noise(x+1, y-1)+noise(x-1, y+1)+noise(x+1, y+1) ) / 16;
    float sides   = ( noise(x-1, y)  +noise(x+1, y)  +noise(x, y-1)  +noise(x, y+1) ) /  8;
    float center  =  noise(x, y) / 4;

    return corners + sides + center;
}

float interpolated_noise(float x, float y)
{
    int x_whole = (int) x;
    float x_frac = x - x_whole;

    int y_whole = (int) y;
    float y_frac = y - y_whole;

    float v1 = smooth_noise_2D(x_whole, y_whole); 
    float v2 = smooth_noise_2D(x_whole, y_whole+1); 
    float v3 = smooth_noise_2D(x_whole+1, y_whole); 
    float v4 = smooth_noise_2D(x_whole+1, y_whole+1); 

    float i1 = cosine_interpolate(v1,v3,x_frac);
    float i2 = cosine_interpolate(v2,v4,x_frac);

    return cosine_interpolate(i1, i2, y_frac);
}


float perlin_noise_2D(float x, float y)
{
    int octaves=5;
    float persistence=0.5;
    float total = 0;

    for(int i=0; i<octaves-1; i++)
    {
        float frequency = pow(2,i);
        float amplitude = pow(persistence,i);
        total = total + interpolated_noise(x * frequency, y * frequency) * amplitude;
    }
    return total;
}

实际上,我正在尝试制作他在文章中所描述的云朵算法。

我使用的是openGL,并且正在制作自己的纹理并将其贴到覆盖屏幕的四边形上。但这些都不重要。在下面的代码中,请知道设置像素函数已经正确工作,它的参数是(x, y, 红色值, 绿色值, 蓝色值)

这基本上就是我的绘制循环:

for(int y=0; y<texture_height; y++)
{
    for(int x=0; x<texture_width; x++)
    {
        seed2+=1;
        float Val=perlin_noise_2D(x,y);
        Val = Val/2.0;
        Val = (Val + 1.0) / 2.0; 
        setPixel(x,y,Val,Val,Val);
    }
}

我得到的是以下内容:

在这里输入图片描述

我该如何调整算法以达到我想要的效果?更改持久性或八度数似乎并没有太大帮助。

1
只是一个猜测:你是否尝试过类似于 perlin_noise_2D((float)x/texture_width,(float)y/texture_height); 的东西?你的结果看起来有点像白噪声,这让我觉得你采样的点之间距离太远了。 - Gigo
@Gigo 我除以10,终于得到了我的云!! - Luke
不错!我把我的评论添加为答案了。 - Gigo
只是一句话:这是一篇关于Perlin噪声的经常被引用的文章,但实际上它并没有讲到真正的Perlin噪声。它使用了一种奇怪的噪声来实现分形布朗运动,而不是Perlin噪声。Perlin噪声本身就是一种噪声函数,而不需要使用八度音阶来使事物看起来很酷。 - Martijn Courteaux
1个回答

3
由于您的结果几乎看起来像白噪声,这可能是由于您在Perlin噪声中采样的间距太大了。尝试使用小于像素坐标的值来评估噪声。
类似于以下内容: perlin_noise_2D((float)x/texture_width,(float)y/texture_height);

除以纹理尺寸太多了,但除以一个较小的数字可以正确工作。 - Luke
2
我建议先按纹理维度进行除法,然后再乘以缩放因子。这样的结果就不会受到纹理分辨率的影响。当然,这取决于你的应用程序。 - Gigo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接