简体   繁体   中英

Software Perlin noise implementation

I have written a 2D Perlin noise implementation based on information from here , here , here , and here . However, the output looks like 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);
}

Any input on what is wrong is appreciated.

EDIT: I found a way to solve this: I used an array of doubles generated at load to fix this. Any way to implement a good random number generator is appreciated though.

I suppose this effect is due to your noise function (all other code looks ok).

The function

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);
}

isn't very noisy but strongly correlated with your input X and Y variables. Try using any other pseudo-random function which you seed with you input.

I reconstructed your code in C and following suggestion from @Howard and this code is working well for me. I am not sure which Interpolate function you used. I used a linear interpolation in my code. I used following noise function:

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);  
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM