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 "transport.h"
00027 #include "volume.h"
00028 #include "film.h"
00029
00030 using namespace lux;
00031
00032
00033 Sampler::Sampler(int xstart, int xend, int ystart, int yend,
00034 int spp) {
00035 xPixelStart = xstart;
00036 xPixelEnd = xend;
00037 yPixelStart = ystart;
00038 yPixelEnd = yend;
00039 samplesPerPixel = spp;
00040 isSampleEnd = true;
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
00047
00048
00049
00050
00051
00052 void Sampler::AddSample(const Sample &sample)
00053 {
00054 film->AddSampleCount(1.f);
00055 for (vector<Sample::Contribution>::const_iterator contribution = sample.contributions.begin(); contribution != sample.contributions.end(); ++contribution) {
00056 if (!(*contribution).color.Black())
00057 film->AddSample((*contribution).imageX,
00058 (*contribution).imageY,
00059 (*contribution).color,
00060 (*contribution).alpha,
00061 (*contribution).buffer,
00062 (*contribution).bufferGroup);
00063 }
00064 }
00065
00066
00067 Sample::Sample(SurfaceIntegrator *surf, VolumeIntegrator *vol,
00068 const Scene *scene)
00069 {
00070 stamp = 0;
00071 sampler = NULL;
00072 surf->RequestSamples(this, scene);
00073 vol->RequestSamples(this, scene);
00074
00075 int nPtrs = n1D.size() + n2D.size() + nxD.size();
00076 if (!nPtrs) {
00077 oneD = twoD = xD = NULL;
00078 return;
00079 }
00080 oneD = (float **)AllocAligned(nPtrs * sizeof(float *));
00081 timexD = (int **)AllocAligned(nxD.size() * sizeof(int *));
00082 twoD = oneD + n1D.size();
00083 xD = twoD + n2D.size();
00084
00085 int totSamples = 0;
00086 int totTime = 0;
00087 for (u_int i = 0; i < n1D.size(); ++i)
00088 totSamples += n1D[i];
00089 for (u_int i = 0; i < n2D.size(); ++i)
00090 totSamples += 2 * n2D[i];
00091 for (u_int i = 0; i < nxD.size(); ++i) {
00092 totSamples += dxD[i] * nxD[i];
00093 totTime += nxD[i];
00094 }
00095
00096 float *mem = (float *)AllocAligned(totSamples *
00097 sizeof(float));
00098 int *tmem = (int *)AllocAligned(totTime * sizeof(int));
00099 for (u_int i = 0; i < n1D.size(); ++i) {
00100 oneD[i] = mem;
00101 mem += n1D[i];
00102 }
00103 for (u_int i = 0; i < n2D.size(); ++i) {
00104 twoD[i] = mem;
00105 mem += 2 * n2D[i];
00106 }
00107 for (u_int i = 0; i < nxD.size(); ++i) {
00108 xD[i] = mem;
00109 mem += dxD[i] * nxD[i];
00110 timexD[i] = tmem;
00111 tmem += nxD[i];
00112 }
00113 }
00114
00115 namespace lux
00116 {
00117
00118
00119 void StratifiedSample1D(float *samp, int nSamples,
00120 bool jitter) {
00121 float invTot = 1.f / nSamples;
00122 for (int i = 0; i < nSamples; ++i) {
00123 float delta = jitter ? lux::random::floatValue() : 0.5f;
00124 *samp++ = (i + delta) * invTot;
00125 }
00126 }
00127 void StratifiedSample2D(float *samp, int nx, int ny,
00128 bool jitter) {
00129 float dx = 1.f / nx, dy = 1.f / ny;
00130 for (int y = 0; y < ny; ++y)
00131 for (int x = 0; x < nx; ++x) {
00132 float jx = jitter ? lux::random::floatValue() : 0.5f;
00133 float jy = jitter ? lux::random::floatValue() : 0.5f;
00134 *samp++ = (x + jx) * dx;
00135 *samp++ = (y + jy) * dy;
00136 }
00137 }
00138 void Shuffle(float *samp, int count, int dims) {
00139 for (int i = 0; i < count; ++i) {
00140 u_int other = lux::random::uintValue() % count;
00141 for (int j = 0; j < dims; ++j)
00142 swap(samp[dims*i + j], samp[dims*other + j]);
00143 }
00144 }
00145 void LatinHypercube(float *samples,
00146 int nSamples, int nDim) {
00147
00148 float delta = 1.f / nSamples;
00149 for (int i = 0; i < nSamples; ++i)
00150 for (int j = 0; j < nDim; ++j)
00151 samples[nDim * i + j] = (i + lux::random::floatValue()) * delta;
00152
00153 for (int i = 0; i < nDim; ++i) {
00154 for (int j = 0; j < nSamples; ++j) {
00155 u_int other = lux::random::uintValue() % nSamples;
00156 swap(samples[nDim * j + i],
00157 samples[nDim * other + i]);
00158 }
00159 }
00160 }
00161
00162 }
00163