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 "lowdiscrepancy.h"
00025 #include "error.h"
00026 #include "vegas.h"
00027
00028 #include "lowdiscrepancypx.h"
00029 #include "tilepx.h"
00030 #include "scene.h"
00031 #include "linear.h"
00032 #include "hilbertpx.h"
00033 #include "dynload.h"
00034
00035 using namespace lux;
00036
00037
00038 LDSampler* LDSampler::clone() const
00039 {
00040 return new LDSampler(*this);
00041 }
00042
00043
00044 LDSampler::LDSampler(int xstart, int xend,
00045 int ystart, int yend, int ps, string pixelsampler)
00046 : Sampler(xstart, xend, ystart, yend, RoundUpPow2(ps)) {
00047 xPos = xPixelStart - 1;
00048 yPos = yPixelStart;
00049
00050
00051 if(pixelsampler == "vegas")
00052 pixelSampler = new VegasPixelSampler(xstart, xend, ystart, yend);
00053 else if(pixelsampler == "lowdiscrepancy")
00054 pixelSampler = new LowdiscrepancyPixelSampler(xstart, xend, ystart, yend);
00055
00056
00057 else if((pixelsampler == "tile") || (pixelsampler == "grid"))
00058 pixelSampler = new TilePixelSampler(xstart, xend, ystart, yend);
00059 else if(pixelsampler == "hilbert")
00060 pixelSampler = new HilbertPixelSampler(xstart, xend, ystart, yend);
00061 else
00062 pixelSampler = new LinearPixelSampler(xstart, xend, ystart, yend);
00063
00064 TotalPixels = pixelSampler->GetTotalPixels();
00065
00066
00067 if (!IsPowerOf2(ps)) {
00068 luxError(LUX_CONSISTENCY,LUX_WARNING,"Pixel samples being rounded up to power of 2");
00069 pixelSamples = RoundUpPow2(ps);
00070 }
00071 else
00072 pixelSamples = ps;
00073 samplePos = pixelSamples;
00074 oneDSamples = twoDSamples = xDSamples = NULL;
00075 imageSamples = new float[7*pixelSamples];
00076 lensSamples = imageSamples + 2*pixelSamples;
00077 timeSamples = imageSamples + 4*pixelSamples;
00078 wavelengthsSamples = imageSamples + 5*pixelSamples;
00079 singleWavelengthSamples = imageSamples + 6*pixelSamples;
00080 n1D = n2D = nxD = 0;
00081 }
00082
00083 LDSampler::~LDSampler() {
00084 delete[] imageSamples;
00085 for (int i = 0; i < n1D; ++i)
00086 delete[] oneDSamples[i];
00087 for (int i = 0; i < n2D; ++i)
00088 delete[] twoDSamples[i];
00089 for (int i = 0; i < nxD; ++i)
00090 delete[] xDSamples[i];
00091 delete[] oneDSamples;
00092 delete[] twoDSamples;
00093 delete[] xDSamples;
00094 }
00095
00096
00097 u_int LDSampler::GetTotalSamplePos() {
00098 return TotalPixels;
00099 }
00100
00101 bool LDSampler::GetNextSample(Sample *sample, u_int *use_pos) {
00102 sample->sampler = this;
00103 if (!oneDSamples) {
00104
00105 oneDSamples = new float *[sample->n1D.size()];
00106 n1D = sample->n1D.size();
00107 for (u_int i = 0; i < sample->n1D.size(); ++i)
00108 oneDSamples[i] = new float[sample->n1D[i] *
00109 pixelSamples];
00110 twoDSamples = new float *[sample->n2D.size()];
00111 n2D = sample->n2D.size();
00112 for (u_int i = 0; i < sample->n2D.size(); ++i)
00113 twoDSamples[i] = new float[2 * sample->n2D[i] *
00114 pixelSamples];
00115 xDSamples = new float *[sample->nxD.size()];
00116 nxD = sample->nxD.size();
00117 for (u_int i = 0; i < sample->nxD.size(); ++i)
00118 xDSamples[i] = new float[sample->dxD[i] * sample->nxD[i] *
00119 pixelSamples];
00120
00121
00122 contribBuffer = film->scene->contribPool->Next(NULL);
00123 }
00124
00125 bool haveMoreSample = true;
00126 if (samplePos == pixelSamples) {
00127
00128 if(!pixelSampler->GetNextPixel(xPos, yPos, use_pos)) {
00129
00130
00131 if (film->enoughSamplePerPixel) {
00132
00133 pixelSampler->renderingDone = true;
00134 haveMoreSample = false;
00135 }
00136 } else
00137 haveMoreSample = (!pixelSampler->renderingDone);
00138
00139 samplePos = 0;
00140
00141 LDShuffleScrambled2D(tspack, 1, pixelSamples, imageSamples);
00142 LDShuffleScrambled2D(tspack, 1, pixelSamples, lensSamples);
00143 LDShuffleScrambled1D(tspack, 1, pixelSamples, timeSamples);
00144 LDShuffleScrambled1D(tspack, 1, pixelSamples, wavelengthsSamples);
00145 LDShuffleScrambled1D(tspack, 1, pixelSamples, singleWavelengthSamples);
00146 for (u_int i = 0; i < sample->n1D.size(); ++i)
00147 LDShuffleScrambled1D(tspack, sample->n1D[i], pixelSamples,
00148 oneDSamples[i]);
00149 for (u_int i = 0; i < sample->n2D.size(); ++i)
00150 LDShuffleScrambled2D(tspack, sample->n2D[i], pixelSamples,
00151 twoDSamples[i]);
00152 float *xDSamp;
00153 for (u_int i = 0; i < sample->nxD.size(); ++i) {
00154 xDSamp = xDSamples[i];
00155 for (u_int j = 0; j < sample->sxD[i].size(); ++j) {
00156 switch (sample->sxD[i][j]) {
00157 case 1: {
00158 LDShuffleScrambled1D(tspack, sample->nxD[i],
00159 pixelSamples, xDSamp);
00160 xDSamp += sample->nxD[i] * pixelSamples;
00161 break; }
00162 case 2: {
00163 LDShuffleScrambled2D(tspack, sample->nxD[i],
00164 pixelSamples, xDSamp);
00165 xDSamp += 2 * sample->nxD[i] * pixelSamples;
00166 break; }
00167 default:
00168 printf("Unsupported dimension\n");
00169 xDSamp += sample->sxD[i][j] * sample->nxD[i] * pixelSamples;
00170 break;
00171 }
00172 }
00173 }
00174 }
00175
00176
00177 if (samplePos >= pixelSamples - 1)
00178 *use_pos = -1;
00179
00180 sample->imageX = xPos + imageSamples[2*samplePos];
00181 sample->imageY = yPos + imageSamples[2*samplePos+1];
00182 sample->lensU = lensSamples[2*samplePos];
00183 sample->lensV = lensSamples[2*samplePos+1];
00184 sample->time = timeSamples[samplePos];
00185 sample->wavelengths = wavelengthsSamples[samplePos];
00186 sample->singleWavelength = singleWavelengthSamples[samplePos];
00187 for (u_int i = 0; i < sample->n1D.size(); ++i) {
00188 int startSamp = sample->n1D[i] * samplePos;
00189 for (u_int j = 0; j < sample->n1D[i]; ++j)
00190 sample->oneD[i][j] = oneDSamples[i][startSamp+j];
00191 }
00192 for (u_int i = 0; i < sample->n2D.size(); ++i) {
00193 int startSamp = 2 * sample->n2D[i] * samplePos;
00194 for (u_int j = 0; j < 2*sample->n2D[i]; ++j)
00195 sample->twoD[i][j] = twoDSamples[i][startSamp+j];
00196 }
00197 ++samplePos;
00198
00199 return haveMoreSample;
00200 }
00201
00202 float *LDSampler::GetLazyValues(Sample *sample, u_int num, u_int pos)
00203 {
00204 float *data = sample->xD[num] + pos * sample->dxD[num];
00205 float *xDSamp = xDSamples[num];
00206 int offset = 0;
00207 for (u_int i = 0; i < sample->sxD[num].size(); ++i) {
00208 if (sample->sxD[num][i] == 1) {
00209 data[offset] = xDSamp[sample->nxD[num] * (samplePos - 1) + pos];
00210 } else if (sample->sxD[num][i] == 2) {
00211 data[offset] = xDSamp[2 * (sample->nxD[num] * (samplePos - 1) + pos)];
00212 data[offset + 1] = xDSamp[2 * (sample->nxD[num] * (samplePos - 1) + pos) + 1];
00213 }
00214 xDSamp += sample->sxD[num][i] * sample->nxD[num] * pixelSamples;
00215 offset += sample->sxD[num][i];
00216 }
00217 return data;
00218 }
00219
00220 Sampler* LDSampler::CreateSampler(const ParamSet ¶ms, const Film *film) {
00221
00222 int xstart, xend, ystart, yend;
00223 film->GetSampleExtent(&xstart, &xend, &ystart, ¥d);
00224 string pixelsampler = params.FindOneString("pixelsampler", "vegas");
00225 int nsamp = params.FindOneInt("pixelsamples", 4);
00226 return new LDSampler(xstart, xend, ystart, yend, nsamp, pixelsampler);
00227 }
00228
00229 static DynamicLoader::RegisterSampler<LDSampler> r("lowdiscrepancy");