2015年10月30日金曜日

Low-Discrepancy Sampling

Efficient Multidimensional Sampling
がレイトレース用のサンプリングとして, いい感じ.
PBRT本では, 計算の仕方は異なるが同じものなはず.



 float radicalInverseVanDerCorput(unsigned bits, unsigned scramble)
{
    bits = bitreverse(bits);
    bits ^= scramble;
    return static_cast<float>(bits) / static_cast<float>(0x100000000L);
}

float radicalInverseSobol(unsigned i, unsigned scramble)
{
    for(unsigned v=1<<31; i; i>>=1, v ^= v>>1){
        if(i&1){
            scramble ^= v;
        }
    }
    return static_cast<float>(scramble) / static_cast<float>(0x100000000L);
}

float radicalInverseLarcherPillichshammer(unsigned i, unsigned scramble)
{
    for(unsigned v=1<<31; i; i>>=1, v |= v>>1){
        if(i&1){
            scramble ^= v;
        }
    }
    return static_cast<float>(scramble) / static_cast<float>(0x100000000L);
}

void sobol02(float& v0, float& v1, unsigned i, unsigned scramble0, unsigned scramble1)
{
    v0 = radicalInverseVanDerCorput(i, scramble0);
    v1 = radicalInverseSobol(i, scramble1);
}

void generate1D(Random& random, float* samples, int size)
{
    unsigned scramble = random.rand();
    for(int i = 0; i < size; ++i){
        v[i] = radicalInverseVanDerCorput(i, scramble);
    }
    shuffle(random, samples, samples+size);
}

void generate2D(Random& random, Sample2D* samples, int size)
{
    unsigned scramble2D[2] = {random.rand(), random.rand()};
    for(int i = 0; i < size; ++i){
        sobol02(samples[i].x_, samples[i].y_, i, scramble2D[0], scramble2D[1]);
    }
    shuffle(random, samples, samples+size);
}

shuffleを入れないと, 収束しなくてはまった.

0 件のコメント:

コメントを投稿