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