提交 d0629f55 编写于 作者: M Matt Pharr

Update from book source.

上级 d229719e
......@@ -30,10 +30,9 @@ std::string Sampler::ToString() const {
// HaltonSampler Method Definitions
HaltonSampler::HaltonSampler(int samplesPerPixel, const Point2i &fullRes,
RandomizeStrategy randomizeStrategy, int seed,
Allocator alloc)
: samplesPerPixel(samplesPerPixel), randomizeStrategy(randomizeStrategy) {
if (randomizeStrategy == RandomizeStrategy::PermuteDigits)
RandomizeStrategy randomize, int seed, Allocator alloc)
: samplesPerPixel(samplesPerPixel), randomize(randomize) {
if (randomize == RandomizeStrategy::PermuteDigits)
digitPermutations = ComputeRadicalInversePermutations(seed, alloc);
// Find radical inverse base scales and exponents that cover sampling area
for (int i = 0; i < 2; ++i) {
......@@ -63,10 +62,10 @@ std::vector<Sampler> HaltonSampler::Clone(int n, Allocator alloc) {
}
std::string HaltonSampler::ToString() const {
return StringPrintf("[ HaltonSampler randomizeStrategy: %s digitPermutations: %p "
return StringPrintf("[ HaltonSampler randomize: %s digitPermutations: %p "
"haltonIndex: %d dimension: %d samplesPerPixel: %d "
"baseScales: %s baseExponents: %s multInverse: [ %d %d ] ]",
randomizeStrategy, digitPermutations, haltonIndex, dimension,
randomize, digitPermutations, haltonIndex, dimension,
samplesPerPixel, baseScales, baseExponents, multInverse[0],
multInverse[1]);
}
......@@ -113,9 +112,8 @@ std::vector<Sampler> SobolSampler::Clone(int n, Allocator alloc) {
std::string PaddedSobolSampler::ToString() const {
return StringPrintf("[ PaddedSobolSampler pixel: %s sampleIndex: %d dimension: %d "
"samplesPerPixel: %d randomizeStrategy: %s ]",
pixel, sampleIndex, dimension, samplesPerPixel,
randomizeStrategy);
"samplesPerPixel: %d randomize: %s ]",
pixel, sampleIndex, dimension, samplesPerPixel, randomize);
}
std::vector<Sampler> PaddedSobolSampler::Clone(int n, Allocator alloc) {
......@@ -169,10 +167,10 @@ std::vector<Sampler> ZSobolSampler::Clone(int n, Allocator alloc) {
}
std::string ZSobolSampler::ToString() const {
return StringPrintf("[ ZSobolSampler randomizeStrategy: %s log2SamplesPerPixel: %d "
return StringPrintf("[ ZSobolSampler randomize: %s log2SamplesPerPixel: %d "
" seed: %d nBase4Digits: %d mortonIndex: %d dimension: %d ]",
randomizeStrategy, log2SamplesPerPixel, seed, nBase4Digits,
mortonIndex, dimension);
randomize, log2SamplesPerPixel, seed, nBase4Digits, mortonIndex,
dimension);
}
ZSobolSampler *ZSobolSampler::Create(const ParameterDictionary &parameters,
......@@ -297,9 +295,8 @@ RandomSampler *RandomSampler::Create(const ParameterDictionary &parameters,
std::string SobolSampler::ToString() const {
return StringPrintf("[ SobolSampler pixel: %s dimension: %d "
"samplesPerPixel: %d scale: %d sobolIndex: %d "
"randomizeStrategy: %s ]",
pixel, dimension, samplesPerPixel, scale, sobolIndex,
randomizeStrategy);
"randomize: %s ]",
pixel, dimension, samplesPerPixel, scale, sobolIndex, randomize);
}
SobolSampler *SobolSampler::Create(const ParameterDictionary &parameters,
......
......@@ -33,7 +33,7 @@ class HaltonSampler {
public:
// HaltonSampler Public Methods
HaltonSampler(int samplesPerPixel, const Point2i &fullResolution,
RandomizeStrategy randomizeStrategy = RandomizeStrategy::PermuteDigits,
RandomizeStrategy randomize = RandomizeStrategy::PermuteDigits,
int seed = 0, Allocator alloc = {});
PBRT_CPU_GPU
......@@ -46,7 +46,7 @@ class HaltonSampler {
int SamplesPerPixel() const { return samplesPerPixel; }
PBRT_CPU_GPU
RandomizeStrategy GetRandomizeStrategy() const { return randomizeStrategy; }
RandomizeStrategy GetRandomizeStrategy() const { return randomize; }
PBRT_CPU_GPU
void StartPixelSample(const Point2i &p, int sampleIndex, int dim) {
......@@ -116,7 +116,7 @@ class HaltonSampler {
PBRT_CPU_GPU
Float SampleDimension(int dimension) const {
switch (randomizeStrategy) {
switch (randomize) {
case RandomizeStrategy::None:
return RadicalInverse(dimension, haltonIndex);
case RandomizeStrategy::CranleyPatterson: {
......@@ -140,7 +140,7 @@ class HaltonSampler {
// HaltonSampler Private Members
int samplesPerPixel;
RandomizeStrategy randomizeStrategy;
RandomizeStrategy randomize;
pstd::vector<DigitPermutation> *digitPermutations = nullptr;
static constexpr int MaxHaltonResolution = 128;
Point2i baseScales, baseExponents;
......@@ -159,7 +159,7 @@ class PaddedSobolSampler {
const FileLoc *loc, Allocator alloc);
PaddedSobolSampler(int samplesPerPixel, RandomizeStrategy randomizer)
: samplesPerPixel(samplesPerPixel), randomizeStrategy(randomizer) {
: samplesPerPixel(samplesPerPixel), randomize(randomizer) {
if (!IsPowerOf2(samplesPerPixel))
Warning("Sobol samplers with non power-of-two sample counts (%d) are "
"sub-optimal.",
......@@ -185,7 +185,7 @@ class PaddedSobolSampler {
int dim = dimension++;
// Return randomized 1D van der Corput sample for dimension _dim_
if (randomizeStrategy == RandomizeStrategy::CranleyPatterson)
if (randomize == RandomizeStrategy::CranleyPatterson)
// Return 1D sample randomized with Cranley-Patterson rotation
return SobolSample(index, 0, CranleyPattersonRotator(BlueNoise(dim, pixel)));
......@@ -203,7 +203,7 @@ class PaddedSobolSampler {
int dim = dimension;
dimension += 2;
// Return randomized 2D Sobol' sample
if (randomizeStrategy == RandomizeStrategy::CranleyPatterson) {
if (randomize == RandomizeStrategy::CranleyPatterson) {
// Return 2D sample randomized with Cranley-Patterson rotation
return {SobolSample(index, 0, CranleyPattersonRotator(BlueNoise(dim, pixel))),
SobolSample(index, 1,
......@@ -224,7 +224,7 @@ class PaddedSobolSampler {
// PaddedSobolSampler Private Methods
PBRT_CPU_GPU
Float SampleDimension(int dimension, uint32_t a, uint32_t hash) const {
switch (randomizeStrategy) {
switch (randomize) {
case RandomizeStrategy::None:
return SobolSample(a, dimension, NoRandomizer());
case RandomizeStrategy::PermuteDigits:
......@@ -241,7 +241,7 @@ class PaddedSobolSampler {
// PaddedSobolSampler Private Members
int samplesPerPixel;
RandomizeStrategy randomizeStrategy;
RandomizeStrategy randomize;
Point2i pixel;
int sampleIndex, dimension;
};
......@@ -250,9 +250,9 @@ class PaddedSobolSampler {
class ZSobolSampler {
public:
ZSobolSampler(int samplesPerPixel, Point2i fullResolution,
RandomizeStrategy randomizeStrategy = RandomizeStrategy::PermuteDigits,
RandomizeStrategy randomize = RandomizeStrategy::PermuteDigits,
int seed = 0)
: randomizeStrategy(randomizeStrategy), seed(seed) {
: randomize(randomize), seed(seed) {
if (!IsPowerOf2(samplesPerPixel)) {
Warning("Rounding %d up to the next power of two for \"zsobol\" sampler "
"samples per pixel.",
......@@ -293,13 +293,13 @@ class ZSobolSampler {
++dimension;
if (randomizeStrategy == RandomizeStrategy::None)
if (randomize == RandomizeStrategy::None)
return SobolSample(sampleIndex, 0, NoRandomizer());
else if (randomizeStrategy == RandomizeStrategy::CranleyPatterson)
else if (randomize == RandomizeStrategy::CranleyPatterson)
return SobolSample(sampleIndex, 0, CranleyPattersonRotator(sampleHash));
else if (randomizeStrategy == RandomizeStrategy::PermuteDigits)
else if (randomize == RandomizeStrategy::PermuteDigits)
return SobolSample(sampleIndex, 0, BinaryPermuteScrambler(sampleHash));
else if (randomizeStrategy == RandomizeStrategy::FastOwen)
else if (randomize == RandomizeStrategy::FastOwen)
return SobolSample(sampleIndex, 0, FastOwenScrambler(sampleHash));
else
return SobolSample(sampleIndex, 0, OwenScrambler(sampleHash));
......@@ -313,16 +313,16 @@ class ZSobolSampler {
dimension += 2;
if (randomizeStrategy == RandomizeStrategy::None)
if (randomize == RandomizeStrategy::None)
return {SobolSample(sampleIndex, 0, NoRandomizer()),
SobolSample(sampleIndex, 1, NoRandomizer())};
else if (randomizeStrategy == RandomizeStrategy::CranleyPatterson)
else if (randomize == RandomizeStrategy::CranleyPatterson)
return {SobolSample(sampleIndex, 0, CranleyPattersonRotator(sampleHash[0])),
SobolSample(sampleIndex, 1, CranleyPattersonRotator(sampleHash[1]))};
else if (randomizeStrategy == RandomizeStrategy::PermuteDigits)
else if (randomize == RandomizeStrategy::PermuteDigits)
return {SobolSample(sampleIndex, 0, BinaryPermuteScrambler(sampleHash[0])),
SobolSample(sampleIndex, 1, BinaryPermuteScrambler(sampleHash[1]))};
else if (randomizeStrategy == RandomizeStrategy::FastOwen)
else if (randomize == RandomizeStrategy::FastOwen)
return {SobolSample(sampleIndex, 0, FastOwenScrambler(sampleHash[0])),
SobolSample(sampleIndex, 1, FastOwenScrambler(sampleHash[1]))};
else
......@@ -369,7 +369,7 @@ class ZSobolSampler {
return uint32_t(MixBits(index ^ (0x55555555 * dimension)) >> 24) % 24;
}
RandomizeStrategy randomizeStrategy;
RandomizeStrategy randomize;
int log2SamplesPerPixel, seed, nBase4Digits;
uint64_t mortonIndex;
int dimension;
......@@ -495,8 +495,8 @@ class SobolSampler {
public:
// SobolSampler Public Methods
SobolSampler(int samplesPerPixel, const Point2i &fullResolution,
RandomizeStrategy randomizeStrategy)
: samplesPerPixel(samplesPerPixel), randomizeStrategy(randomizeStrategy) {
RandomizeStrategy randomize)
: samplesPerPixel(samplesPerPixel), randomize(randomize) {
if (!IsPowerOf2(samplesPerPixel))
Warning("Non power-of-two sample count %d will perform sub-optimally with "
"the SobolSampler.",
......@@ -557,16 +557,16 @@ class SobolSampler {
PBRT_CPU_GPU
Float SampleDimension(int dimension) const {
// Return un-randomized Sobol sample if appropriate
if (dimension < 2 || randomizeStrategy == RandomizeStrategy::None)
if (dimension < 2 || randomize == RandomizeStrategy::None)
return SobolSample(sobolIndex, dimension, NoRandomizer());
// Return randomized Sobol sample using _randomizeStrategy_
// Return randomized Sobol sample using _randomize_
uint32_t hash = MixBits((uint64_t(dimension) << 32) ^ GetOptions().seed);
if (randomizeStrategy == RandomizeStrategy::CranleyPatterson)
if (randomize == RandomizeStrategy::CranleyPatterson)
return SobolSample(sobolIndex, dimension, CranleyPattersonRotator(hash));
else if (randomizeStrategy == RandomizeStrategy::PermuteDigits)
else if (randomize == RandomizeStrategy::PermuteDigits)
return SobolSample(sobolIndex, dimension, BinaryPermuteScrambler(hash));
else if (randomizeStrategy == RandomizeStrategy::FastOwen)
else if (randomize == RandomizeStrategy::FastOwen)
return SobolSample(sobolIndex, dimension, FastOwenScrambler(hash));
else
return SobolSample(sobolIndex, dimension, OwenScrambler(hash));
......@@ -574,7 +574,7 @@ class SobolSampler {
// SobolSampler Private Members
int samplesPerPixel, scale;
RandomizeStrategy randomizeStrategy;
RandomizeStrategy randomize;
Point2i pixel;
int dimension;
int64_t sobolIndex;
......
......@@ -30,15 +30,15 @@ class DigitPermutation {
CHECK_LT(base, 65536); // uint16_t
// Compute number of digits needed for _base_
nDigits = 0;
Float invBase = (Float)1 / (Float)base, invBaseN = 1;
while (1 - invBaseN < 1) {
Float invBase = (Float)1 / (Float)base, invBaseM = 1;
while (1 - invBaseM < 1) {
++nDigits;
invBaseN *= invBase;
invBaseM *= invBase;
}
permutations = alloc.allocate_object<uint16_t>(nDigits * base);
// Compute random permutations for all digits
for (int digitIndex = 0; digitIndex < nDigits; ++digitIndex) {
// Compute random permutation for _digitIndex_
uint32_t digitSeed = MixBits(((base << 8) + digitIndex) ^ seed);
for (int digitValue = 0; digitValue < base; ++digitValue) {
int index = digitIndex * base + digitValue;
......@@ -97,8 +97,8 @@ PBRT_CPU_GPU inline Float RadicalInverse(int baseIndex, uint64_t a) {
return std::min(reversedDigits * invBaseN, OneMinusEpsilon);
}
PBRT_CPU_GPU
inline uint64_t InverseRadicalInverse(uint64_t inverse, int base, int nDigits) {
PBRT_CPU_GPU inline uint64_t InverseRadicalInverse(uint64_t inverse, int base,
int nDigits) {
uint64_t index = 0;
for (int i = 0; i < nDigits; ++i) {
uint64_t digit = inverse % base;
......@@ -111,38 +111,39 @@ inline uint64_t InverseRadicalInverse(uint64_t inverse, int base, int nDigits) {
PBRT_CPU_GPU inline Float ScrambledRadicalInverse(int baseIndex, uint64_t a,
const DigitPermutation &perm) {
int base = Primes[baseIndex];
Float invBase = (Float)1 / (Float)base, invBaseN = 1;
Float invBase = (Float)1 / (Float)base, invBaseM = 1;
uint64_t reversedDigits = 0;
int digitIndex = 0;
while (1 - invBaseN < 1) {
while (1 - invBaseM < 1) {
// Permute least significant digit from _a_ and update _reversedDigits_
uint64_t next = a / base;
int digitValue = a - next * base;
reversedDigits = reversedDigits * base + perm.Permute(digitIndex, digitValue);
invBaseN *= invBase;
invBaseM *= invBase;
++digitIndex;
a = next;
}
return std::min(invBaseN * reversedDigits, OneMinusEpsilon);
return std::min(invBaseM * reversedDigits, OneMinusEpsilon);
}
PBRT_CPU_GPU inline Float OwenScrambledRadicalInverse(int baseIndex, uint64_t a,
uint32_t hash) {
int base = Primes[baseIndex];
Float invBase = (Float)1 / (Float)base, invBaseN = 1;
Float invBase = (Float)1 / (Float)base, invBaseM = 1;
uint64_t reversedDigits = 0;
int digitIndex = 0;
while (1 - invBaseN < 1) {
while (1 - invBaseM < 1) {
// Compute Owen-scrambled digit for _digitIndex_
uint64_t next = a / base;
int digitValue = a - next * base;
uint32_t digitHash = MixBits(hash ^ reversedDigits);
digitValue = PermutationElement(digitValue, base, digitHash);
reversedDigits = reversedDigits * base + digitValue;
invBaseN *= invBase;
invBaseM *= invBase;
++digitIndex;
a = next;
}
return std::min(invBaseN * reversedDigits, OneMinusEpsilon);
return std::min(invBaseM * reversedDigits, OneMinusEpsilon);
}
PBRT_CPU_GPU inline uint32_t MultiplyGenerator(pstd::span<const uint32_t> C, uint32_t a) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册