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 "halton.h"
00025 #include "error.h"
00026 #include "vegas.h"
00027 #include "randompx.h"
00028 #include "lowdiscrepancypx.h"
00029 #include "linear.h"
00030 #include "tilepx.h"
00031
00032 using namespace lux;
00033
00034
00035 HaltonSampler* HaltonSampler::clone() const
00036 {
00037 return new HaltonSampler(*this);
00038 }
00039
00040
00041 HaltonSampler::HaltonSampler(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 HaltonSampler::~HaltonSampler() {
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 HaltonSampler::GetTotalSamplePos() {
00094 return TotalPixels;
00095 }
00096
00097 bool HaltonSampler::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 (int i = 0; i < nxD; ++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 HaltonShuffleScrambled2D(1, pixelSamples, imageSamples);
00135 HaltonShuffleScrambled2D(1, pixelSamples, lensSamples);
00136 HaltonShuffleScrambled1D(1, pixelSamples, timeSamples);
00137 for (u_int i = 0; i < sample->n1D.size(); ++i)
00138 HaltonShuffleScrambled1D(sample->n1D[i], pixelSamples,
00139 oneDSamples[i]);
00140 for (u_int i = 0; i < sample->n2D.size(); ++i)
00141 HaltonShuffleScrambled2D(sample->n2D[i], pixelSamples,
00142 twoDSamples[i]);
00143 float *xDSamp;
00144 for (u_int i = 0; i < sample->nxD.size(); ++i) {
00145 xDSamp = xDSamples[i];
00146 for (u_int j = 0; j < sample->sxD[i].size(); ++j) {
00147 switch (sample->sxD[i][j]) {
00148 case 1: {
00149 HaltonShuffleScrambled1D(sample->nxD[i],
00150 pixelSamples, xDSamp);
00151 xDSamp += sample->nxD[i] * pixelSamples;
00152 break; }
00153 case 2: {
00154 HaltonShuffleScrambled2D(sample->nxD[i],
00155 pixelSamples, xDSamp);
00156 xDSamp += 2 * sample->nxD[i] * pixelSamples;
00157 break; }
00158 default:
00159 printf("Unsupported dimension\n");
00160 xDSamp += sample->sxD[i][j] * sample->nxD[i] * pixelSamples;
00161 break;
00162 }
00163 }
00164 }
00165 }
00166
00167 if (samplePos >= pixelSamples-1)
00168 *use_pos = -1;
00169
00170 sample->imageX = xPos + imageSamples[2*samplePos];
00171 sample->imageY = yPos + imageSamples[2*samplePos+1];
00172 sample->lensU = lensSamples[2*samplePos];
00173 sample->lensV = lensSamples[2*samplePos+1];
00174 sample->time = timeSamples[samplePos];
00175 sample->wavelengths = wavelengthsSamples[samplePos];
00176 sample->singleWavelength = lux::random::floatValue();
00177 for (u_int i = 0; i < sample->n1D.size(); ++i) {
00178 int startSamp = sample->n1D[i] * samplePos;
00179 for (u_int j = 0; j < sample->n1D[i]; ++j)
00180 sample->oneD[i][j] = oneDSamples[i][startSamp+j];
00181 }
00182 for (u_int i = 0; i < sample->n2D.size(); ++i) {
00183 int startSamp = 2 * sample->n2D[i] * samplePos;
00184 for (u_int j = 0; j < 2*sample->n2D[i]; ++j)
00185 sample->twoD[i][j] = twoDSamples[i][startSamp+j];
00186 }
00187 ++samplePos;
00188 return haveMoreSample;
00189 }
00190 float *HaltonSampler::GetLazyValues(Sample *sample, u_int num, u_int pos)
00191 {
00192 float *data = sample->xD[num] + pos * sample->dxD[num];
00193 float *xDSamp = xDSamples[num];
00194 int offset = 0;
00195 for (u_int i = 0; i < sample->sxD[num].size(); ++i) {
00196 if (sample->sxD[num][i] == 1) {
00197 data[offset] = xDSamp[sample->nxD[num] * (samplePos - 1) + pos];
00198 } else if (sample->sxD[num][i] == 2) {
00199 data[offset] = xDSamp[2 * (sample->nxD[num] * (samplePos - 1) + pos)];
00200 data[offset + 1] = xDSamp[2 * (sample->nxD[num] * (samplePos - 1) + pos) + 1];
00201 }
00202 xDSamp += sample->sxD[num][i] * sample->nxD[num] * pixelSamples;
00203 offset += sample->sxD[num][i];
00204 }
00205 return data;
00206 }
00207 Sampler* HaltonSampler::CreateSampler(const ParamSet ¶ms, const Film *film) {
00208
00209 int xstart, xend, ystart, yend;
00210 film->GetSampleExtent(&xstart, &xend, &ystart, ¥d);
00211 string pixelsampler = params.FindOneString("pixelsampler", "vegas");
00212 int nsamp = params.FindOneInt("pixelsamples", 4);
00213 return new HaltonSampler(xstart, xend, ystart, yend, nsamp, pixelsampler);
00214 }