软件Perlin噪声实现

时间:2011-08-07 14:28:25

标签: c# perlin-noise

我根据herehereherehere的信息编写了2D Perlin噪声实现。但是,输出看起来像this

public static double Perlin(double X, double XScale, double Y, double YScale, double Persistance, double Octaves) {
    double total=0.0;
    for(int i=0;i<Octaves;i++){
        int frq = (int) Math.Pow(2,i);
        int amp = (int) Math.Pow(Persistance,i);
        total += InterpolatedSmoothNoise((X / XScale) * frq, (Y / YScale) * frq) * amp;
    }
return total;
}

private static double InterpolatedSmoothNoise (double X, double Y) {
int ix = (int) Math.Floor(X);
double fx = X-ix;
int iy = (int) Math.Floor(Y);
double fy = Y-iy;

double v1 = SmoothPerlin(ix,iy); //          --
double v2 = SmoothPerlin(ix+1,iy); //        +-
double v3 = SmoothPerlin(ix,iy+1);//         -+
double v4 = SmoothPerlin(ix+1,iy+1);//       ++

double i1 = Interpolate(v1,v2,fx);
double i2 = Interpolate(v3,v4,fx);

    return Interpolate(i1,i2,fy);
}

private static double SmoothPerlin (int X, int Y) {
    double sides=(Noise(X-1,Y,Z)+Noise(X+1,Y,Z)+Noise(X,Y-1,Z)+Noise(X,Y+1,Z)+Noise(X,Y,Z-1)+Noise(X,Y,Z+1))/12.0;
    double center=Noise(X,Y,Z)/2.0;
    return sides + center;
}

private static double Noise (int X, int Y) {
uint m_z = (uint) (36969 * (X & 65535) + (X >> 16));
uint m_w = (uint) (18000 * (Y & 65535) + (Y >> 16));
uint ou = (m_z << 16) + m_w;
return ((ou + 1.0) * 2.328306435454494e-10);
}

对错误的任何输入表示赞赏。

编辑:我找到了解决这个问题的方法:我使用了一个在加载时生成的双精度数组来解决这个问题。不过,任何实现好的随机数发生器的方法都是值得赞赏的。

2 个答案:

答案 0 :(得分:1)

我认为这种效果是由于你的噪音功能(所有其他代码看起来都不错)。

功能

private static double Noise (int X, int Y) {
    uint m_z = (uint) (36969 * (X & 65535) + (X >> 16));
    uint m_w = (uint) (18000 * (Y & 65535) + (Y >> 16));
    uint ou = (m_z << 16) + m_w;
    return ((ou + 1.0) * 2.328306435454494e-10);
}

不是很嘈杂,但与您的输入XY变量密切相关。尝试使用随输入种子的任何其他伪随机函数。

答案 1 :(得分:1)

我在C中重构了你的代码并遵循@Howard的建议,这段代码对我来说效果很好。我不确定您使用的是哪种Interpolate功能。我在代码中使用了线性插值。我使用了以下噪音功能:

static double Noise2(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);  
}