int HaltonSampler::GetMoreSamples(Sample *samples, RNG &rng) { retry: if (currentSample >= wantedSamples) return 0; // Generate sample with Halton sequence and reject if outside image extent float u = (float)RadicalInverse(currentSample, 3); float v = (float)RadicalInverse(currentSample, 2); float lerpDelta = float(max(xPixelEnd - xPixelStart, yPixelEnd - yPixelStart)); samples->imageX = Lerp(u, xPixelStart, xPixelStart + lerpDelta); samples->imageY = Lerp(v, yPixelStart, yPixelStart + lerpDelta); ++currentSample; if (samples->imageX >= xPixelEnd || samples->imageY >= yPixelEnd) goto retry; // Generate lens, time, and integrator samples for _HaltonSampler_ samples->lensU = (float)RadicalInverse(currentSample, 5); samples->lensV = (float)RadicalInverse(currentSample, 7); samples->time = Lerp((float)RadicalInverse(currentSample, 11), shutterOpen, shutterClose); for (uint32_t i = 0; i < samples->n1D.size(); ++i) LatinHypercube(samples->oneD[i], samples->n1D[i], 1, rng); for (uint32_t i = 0; i < samples->n2D.size(); ++i) LatinHypercube(samples->twoD[i], samples->n2D[i], 2, rng); return 1; }
int StratifiedSampler::GetMoreSamples(Sample *samples, RNG &rng) { if (yPos == yPixelEnd) return 0; int nSamples = xPixelSamples * yPixelSamples; // Generate stratified camera samples for _(xPos, yPos)_ // Generate initial stratified samples into _sampleBuf_ memory float *bufp = sampleBuf; float *imageSamples = bufp; bufp += 2 * nSamples; float *lensSamples = bufp; bufp += 2 * nSamples; float *timeSamples = bufp; StratifiedSample2D(imageSamples, xPixelSamples, yPixelSamples, rng, jitterSamples); StratifiedSample2D(lensSamples, xPixelSamples, yPixelSamples, rng, jitterSamples); StratifiedSample1D(timeSamples, xPixelSamples * yPixelSamples, rng, jitterSamples); // Shift stratified image samples to pixel coordinates for (int o = 0; o < 2 * xPixelSamples * yPixelSamples; o += 2) { imageSamples[o] += xPos; imageSamples[o+1] += yPos; } // Decorrelate sample dimensions Shuffle(lensSamples, xPixelSamples*yPixelSamples, 2, rng); Shuffle(timeSamples, xPixelSamples*yPixelSamples, 1, rng); // Initialize stratified _samples_ with sample values for (int i = 0; i < nSamples; ++i) { samples[i].imageX = imageSamples[2*i]; samples[i].imageY = imageSamples[2*i+1]; samples[i].lensU = lensSamples[2*i]; samples[i].lensV = lensSamples[2*i+1]; samples[i].time = Lerp(timeSamples[i], shutterOpen, shutterClose); // Generate stratified samples for integrators for (uint32_t j = 0; j < samples[i].n1D.size(); ++j) LatinHypercube(samples[i].oneD[j], samples[i].n1D[j], 1, rng); for (uint32_t j = 0; j < samples[i].n2D.size(); ++j) LatinHypercube(samples[i].twoD[j], samples[i].n2D[j], 2, rng); } // Advance to next pixel for stratified sampling if (++xPos == xPixelEnd) { xPos = xPixelStart; ++yPos; } return nSamples; }
SWCSpectrum BxDF::rho(const SpectrumWavelengths &sw, const Vector &w, u_int nSamples, float *samples) const { if (!samples) { samples = static_cast<float *>(alloca(2 * nSamples * sizeof(float))); LatinHypercube(rng, samples, nSamples, 2); } Vector wi; float pdf; SWCSpectrum r(0.f); for (u_int i = 0; i < nSamples; ++i) { // Estimate one term of $\rho_{dh}$ // SampleF will add the BxDF to r if the sampling is successfull SampleF(sw, w, &wi, samples[2 * i], samples[2 * i + 1], &r, &pdf, NULL, true); } return r / nSamples; }
Spectrum BxDF::rho(const Vector &w, int nSamples, float *samples) const { if (!samples) { samples = (float *)alloca(2 * nSamples * sizeof(float)); LatinHypercube(samples, nSamples, 2); } Spectrum r = 0.; for (int i = 0; i < nSamples; ++i) { // Estimate one term of $\rho_{dh}$ Vector wi; float pdf = 0.f; Spectrum f = Sample_f(w, &wi, samples[2*i], samples[2*i+1], &pdf); if (pdf > 0.) r += f * fabsf(wi.z) / pdf; } return r / nSamples; }
Spectrum BxDF::rho(int nSamples, float *samples) const { if (!samples) { samples = (float *)alloca(4 * nSamples * sizeof(float)); LatinHypercube(samples, nSamples, 4); } Spectrum r = 0.; for (int i = 0; i < nSamples; ++i) { // Estimate one term of $\rho_{hh}$ Vector wo, wi; wo = UniformSampleHemisphere(samples[4*i], samples[4*i+1]); float pdf_o = INV_TWOPI, pdf_i = 0.f; Spectrum f = Sample_f(wo, &wi, samples[4*i+2], samples[4*i+3], &pdf_i); if (pdf_i > 0.) r += f * fabsf(wi.z * wo.z) / (pdf_o * pdf_i); } return r / (M_PI*nSamples); }
SWCSpectrum BxDF::rho(const SpectrumWavelengths &sw, u_int nSamples, float *samples) const { if (!samples) { samples = static_cast<float *>(alloca(4 * nSamples * sizeof(float))); LatinHypercube(rng, samples, nSamples, 4); } SWCSpectrum r(0.f); for (u_int i = 0; i < nSamples; ++i) { // Estimate one term of $\rho_{hh}$ const Vector wo(UniformSampleSphere(samples[4 * i], samples[4 * i + 1])); const float pdfo = INV_TWOPI * .5f; Vector wi; float pdfi = 0.f; SWCSpectrum f(0.f); if (SampleF(sw, wo, &wi, samples[4 * i + 2], samples[4 * i + 3], &f, &pdfi, NULL, true)) r.AddWeighted(fabsf(wo.z) / pdfo, f); } return r / (M_PI * nSamples); }