00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "pbrt.h"
00026 #include "sampling.h"
00027 #include "transport.h"
00028 #include "volume.h"
00029
00030 Sampler::~Sampler() {
00031 }
00032 Sampler::Sampler(int xstart, int xend, int ystart, int yend,
00033 int spp) {
00034 xPixelStart = xstart;
00035 xPixelEnd = xend;
00036 yPixelStart = ystart;
00037 yPixelEnd = yend;
00038 samplesPerPixel = spp;
00039 }
00040
00041 Sample::Sample(SurfaceIntegrator *surf,
00042 VolumeIntegrator *vol, const Scene *scene) {
00043 surf->RequestSamples(this, scene);
00044 vol->RequestSamples(this, scene);
00045
00046 int nPtrs = n1D.size() + n2D.size();
00047 if (!nPtrs) {
00048 oneD = twoD = NULL;
00049 return;
00050 }
00051 oneD = (float **)AllocAligned(nPtrs * sizeof(float *));
00052 twoD = oneD + n1D.size();
00053
00054 int totSamples = 0;
00055 for (u_int i = 0; i < n1D.size(); ++i)
00056 totSamples += n1D[i];
00057 for (u_int i = 0; i < n2D.size(); ++i)
00058 totSamples += 2 * n2D[i];
00059
00060 float *mem = (float *)AllocAligned(totSamples *
00061 sizeof(float));
00062 for (u_int i = 0; i < n1D.size(); ++i) {
00063 oneD[i] = mem;
00064 mem += n1D[i];
00065 }
00066 for (u_int i = 0; i < n2D.size(); ++i) {
00067 twoD[i] = mem;
00068 mem += 2 * n2D[i];
00069 }
00070 }
00071
00072 COREDLL void StratifiedSample1D(float *samp, int nSamples,
00073 bool jitter) {
00074 float invTot = 1.f / nSamples;
00075 for (int i = 0; i < nSamples; ++i) {
00076 float delta = jitter ? RandomFloat() : 0.5f;
00077 *samp++ = (i + delta) * invTot;
00078 }
00079 }
00080 COREDLL void StratifiedSample2D(float *samp, int nx, int ny,
00081 bool jitter) {
00082 float dx = 1.f / nx, dy = 1.f / ny;
00083 for (int y = 0; y < ny; ++y)
00084 for (int x = 0; x < nx; ++x) {
00085 float jx = jitter ? RandomFloat() : 0.5f;
00086 float jy = jitter ? RandomFloat() : 0.5f;
00087 *samp++ = (x + jx) * dx;
00088 *samp++ = (y + jy) * dy;
00089 }
00090 }
00091 COREDLL void Shuffle(float *samp, int count, int dims) {
00092 for (int i = 0; i < count; ++i) {
00093 u_int other = RandomUInt() % count;
00094 for (int j = 0; j < dims; ++j)
00095 swap(samp[dims*i + j], samp[dims*other + j]);
00096 }
00097 }
00098 COREDLL void LatinHypercube(float *samples,
00099 int nSamples, int nDim) {
00100
00101 float delta = 1.f / nSamples;
00102 for (int i = 0; i < nSamples; ++i)
00103 for (int j = 0; j < nDim; ++j)
00104 samples[nDim * i + j] = (i + RandomFloat()) * delta;
00105
00106 for (int i = 0; i < nDim; ++i) {
00107 for (int j = 0; j < nSamples; ++j) {
00108 u_int other = RandomUInt() % nSamples;
00109 swap(samples[nDim * j + i],
00110 samples[nDim * other + i]);
00111 }
00112 }
00113 }