00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "lux.h"
00025 #include "sampling.h"
00026 #include "scene.h"
00027 #include "transport.h"
00028 #include "volume.h"
00029 #include "film.h"
00030
00031 using namespace lux;
00032
00033
00034 Sampler::Sampler(int xstart, int xend, int ystart, int yend,
00035 int spp) {
00036 xPixelStart = xstart;
00037 xPixelEnd = xend;
00038 yPixelStart = ystart;
00039 yPixelEnd = yend;
00040 samplesPerPixel = spp;
00041 }
00042 float *Sampler::GetLazyValues(Sample *sample, u_int num, u_int pos)
00043 {
00044 return sample->xD[num] + pos * sample->dxD[num];
00045 }
00046 void Sampler::AddSample(const Sample &sample)
00047 {
00048 contribBuffer->AddSampleCount(1.f);
00049 for (u_int i=0; i<sample.contributions.size(); i++) {
00050
00051 if(!contribBuffer->Add(&sample.contributions[i], 1.f)) {
00052 contribBuffer = film->scene->contribPool->Next(contribBuffer);
00053 contribBuffer->Add(&sample.contributions[i], 1.f);
00054 }
00055 }
00056 sample.contributions.clear();
00057 }
00058
00059
00060 Sample::Sample(SurfaceIntegrator *surf, VolumeIntegrator *vol,
00061 const Scene *scene)
00062 {
00063 stamp = 0;
00064 sampler = NULL;
00065 surf->RequestSamples(this, scene);
00066 vol->RequestSamples(this, scene);
00067
00068 int nPtrs = n1D.size() + n2D.size() + nxD.size();
00069 if (!nPtrs) {
00070 oneD = twoD = xD = NULL;
00071 return;
00072 }
00073 oneD = AllocAligned<float *>(nPtrs);
00074 timexD = AllocAligned<int *>(nxD.size());
00075 twoD = oneD + n1D.size();
00076 xD = twoD + n2D.size();
00077
00078 int totSamples = 0;
00079 int totTime = 0;
00080 for (u_int i = 0; i < n1D.size(); ++i)
00081 totSamples += n1D[i];
00082 for (u_int i = 0; i < n2D.size(); ++i)
00083 totSamples += 2 * n2D[i];
00084 for (u_int i = 0; i < nxD.size(); ++i) {
00085 totSamples += dxD[i] * nxD[i];
00086 totTime += nxD[i];
00087 }
00088
00089 float *mem = AllocAligned<float>(totSamples);
00090 int *tmem = AllocAligned<int>(totTime);
00091
00092 oneD[0] = mem;
00093 for (u_int i = 0; i < n1D.size(); ++i) {
00094 oneD[i] = mem;
00095 mem += n1D[i];
00096 }
00097 for (u_int i = 0; i < n2D.size(); ++i) {
00098 twoD[i] = mem;
00099 mem += 2 * n2D[i];
00100 }
00101
00102 timexD[0] = tmem;
00103 for (u_int i = 0; i < nxD.size(); ++i) {
00104 xD[i] = mem;
00105 mem += dxD[i] * nxD[i];
00106 timexD[i] = tmem;
00107 tmem += nxD[i];
00108 }
00109 }
00110
00111 namespace lux
00112 {
00113
00114
00115 void StratifiedSample1D(const TsPack *tspack, float *samp, int nSamples,
00116 bool jitter) {
00117 float invTot = 1.f / nSamples;
00118 for (int i = 0; i < nSamples; ++i) {
00119 float delta = jitter ? tspack->rng->floatValue() : 0.5f;
00120 *samp++ = (i + delta) * invTot;
00121 }
00122 }
00123 void StratifiedSample2D(const TsPack *tspack, float *samp, int nx, int ny,
00124 bool jitter) {
00125 float dx = 1.f / nx, dy = 1.f / ny;
00126 for (int y = 0; y < ny; ++y)
00127 for (int x = 0; x < nx; ++x) {
00128 float jx = jitter ? tspack->rng->floatValue() : 0.5f;
00129 float jy = jitter ? tspack->rng->floatValue() : 0.5f;
00130 *samp++ = (x + jx) * dx;
00131 *samp++ = (y + jy) * dy;
00132 }
00133 }
00134 void Shuffle(const TsPack *tspack, float *samp, int count, int dims) {
00135 for (int i = 0; i < count; ++i) {
00136 u_int other = tspack->rng->uintValue() % count;
00137 for (int j = 0; j < dims; ++j)
00138 swap(samp[dims*i + j], samp[dims*other + j]);
00139 }
00140 }
00141 void LatinHypercube(const TsPack *tspack, float *samples,
00142 int nSamples, int nDim) {
00143
00144 float delta = 1.f / nSamples;
00145 for (int i = 0; i < nSamples; ++i)
00146 for (int j = 0; j < nDim; ++j)
00147 samples[nDim * i + j] = (i + tspack->rng->floatValue()) * delta;
00148
00149 for (int i = 0; i < nDim; ++i) {
00150 for (int j = 0; j < nSamples; ++j) {
00151 u_int other = tspack->rng->uintValue() % nSamples;
00152 swap(samples[nDim * j + i],
00153 samples[nDim * other + i]);
00154 }
00155 }
00156 }
00157
00158 }
00159