がレイトレース用のサンプリングとして, いい感じ.
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 件のコメント:
コメントを投稿