Программная реализация Perlin noise - PullRequest
0 голосов
/ 07 августа 2011

Я написал реализацию 2D-шума Перлина, основанную на информации из здесь , здесь , здесь и здесь .Однако вывод выглядит так: 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 ]

1 голос
/ 07 августа 2011

Я восстановил ваш код в C и следовал совету @Howard, и этот код работает хорошо для меня. Я не уверен, какую функцию интерполяции вы использовали. Я использовал линейную интерполяцию в моем коде. Я использовал следующую функцию шума:

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);  
}
1 голос
/ 07 августа 2011

Полагаю, этот эффект связан с вашей функцией шума (весь другой код выглядит нормально).

Функция

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

не очень шумно, но сильно коррелирует с вашими входными переменными X и Y. Попробуйте использовать любую другую псевдослучайную функцию, которую вы вводите с помощью ввода.

...