Симплексный диапазон шума слишком мал - PullRequest
2 голосов
/ 22 мая 2019

Я использую следующую реализацию симплексного шума (Приложение B): https://www.csee.umbc.edu/~olano/s2002c36/ch02.pdf

Это было написано самим Кеном Перлином.

Код в PDF написан на JAVAно я перевел это на C ++.Вот мой код (вы также можете запустить его на C ++ Shell ):

#include <iostream>
#include <string>
#include <cmath>

int i,j,k, A[3] = {0,0,0};
float u,v,w;

int T[8] = {0x15,0x38,0x32,0x2c,0x0d,0x13,0x07,0x2a};
int b(int N, int B) { return N>>B & 1; }
int b(int i, int j, int k, int B) { return T[b(i,B)<<2 | b(j,B)<<1 | b(k,B)]; }

int shuffle(int i, int j, int k) {
    return b(i,j,k,0) + b(j,k,i,1) + b(k,i,j,2) + b(i,j,k,3) +
    b(j,k,i,4) + b(k,i,j,5) + b(i,j,k,6) + b(j,k,i,7) ;
}

float K(int a) {
    float s = (A[0]+A[1]+A[2])/6.;
    float x = u-A[0]+s, y = v-A[1]+s, z = w-A[2]+s, t = .6-x*x-y*y-z*z;
    int h = shuffle(i+A[0],j+A[1],k+A[2]);
    A[a]++;
    if (t < 0)
    return 0;
    int b5 = h>>5 & 1, b4 = h>>4 & 1, b3 = h>>3 & 1, b2= h>>2 & 1, b = h & 3;
    float p = b==1?x:b==2?y:z, q = b==1?y:b==2?z:x, r = b==1?z:b==2?x:y;
    p = (b5==b3 ? -p : p); q = (b5==b4 ? -q : q); r = (b5!=(b4^b3) ? -r : r);
    t *= t;
    return 8 * t * t * (p + (b==0 ? q+r : b2==0 ? q : r));
}

float noise(float x, float y, float z) {
    float s = (x+y+z)/3;
    i=(int)floorf(x+s); j=(int)floorf(y+s); k=(int)floorf(z+s);
    s = (i+j+k)/6.; u = x-i+s; v = y-j+s; w = z-k+s;
    A[0]=A[1]=A[2]=0;
    int hi = u>=w ? u>=v ? 0 : 1 : v>=w ? 1 : 2;
    int lo = u< w ? u< v ? 0 : 1 : v< w ? 1 : 2;
    return K(hi) + K(3-hi-lo) + K(lo) + K(0);
}

int main() {
    float scale = 0.0007f;
    float min = 1.0f;
    float max = -1.0f;
    for (int x = 0; x < 100000; x++) {
        float v = noise(x * scale, 0.0f, 0.0f);
        if (v > max) max = v;
        if (v < min) min = v;
    }
    printf("min = %f\r\n", min);
    printf("max = %f\r\n", max);
}

Проблема в том, что при вызове функции шума я получаю значения только в диапазоне от -0,3 до 0,3.

Я ожидал получить значения от -1,0 до 1,0.

Есть ли проблемы с этой конкретной реализацией?

Obs: Я не нормализую вывод и невычисление любых дополнительных октав пока.

1 Ответ

0 голосов
/ 22 мая 2019

Я пришел к решению, которое, я уверен, не является правильным способом сделать это.

Я изменил это:

return 8 * t * t * (p + (b==0 ? q+r : b2==0 ? q : r));

На это:

return 26 * t * t * (p + (b==0 ? q+r : b2==0 ? q : r));

Теперь я получаю хороший вывод.

...