00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PBRT_SAMPLING_H
00025 #define PBRT_SAMPLING_H
00026
00027 #include "pbrt.h"
00028 #include "geometry.h"
00029
00030 class COREDLL Sampler {
00031 public:
00032
00033 virtual ~Sampler();
00034 Sampler(int xstart, int xend,
00035 int ystart, int yend,
00036 int spp);
00037 virtual bool GetNextSample(Sample *sample) = 0;
00038 int TotalSamples() const {
00039 return samplesPerPixel *
00040 (xPixelEnd - xPixelStart) *
00041 (yPixelEnd - yPixelStart);
00042 }
00043 virtual int RoundSize(int size) const = 0;
00044
00045 int xPixelStart, xPixelEnd, yPixelStart, yPixelEnd;
00046 int samplesPerPixel;
00047 };
00048 struct Sample {
00049
00050 Sample(SurfaceIntegrator *surf, VolumeIntegrator *vol,
00051 const Scene *scene);
00052 u_int Add1D(u_int num) {
00053 n1D.push_back(num);
00054 return n1D.size()-1;
00055 }
00056 u_int Add2D(u_int num) {
00057 n2D.push_back(num);
00058 return n2D.size()-1;
00059 }
00060 ~Sample() {
00061 if (oneD != NULL) {
00062 FreeAligned(oneD[0]);
00063 FreeAligned(oneD);
00064 }
00065 }
00066
00067 float imageX, imageY;
00068 float lensU, lensV;
00069 float time;
00070
00071 vector<u_int> n1D, n2D;
00072 float **oneD, **twoD;
00073 };
00074 COREDLL void StratifiedSample1D(float *samples,
00075 int nsamples,
00076 bool jitter = true);
00077 COREDLL void StratifiedSample2D(float *samples,
00078 int nx, int ny,
00079 bool jitter = true);
00080 COREDLL void Shuffle(float *samp, int count, int dims);
00081 COREDLL
00082 void LatinHypercube(float *samples, int nSamples, int nDim);
00083 inline double RadicalInverse(int n, int base) {
00084 double val = 0;
00085 double invBase = 1. / base, invBi = invBase;
00086 while (n > 0) {
00087
00088 int d_i = (n % base);
00089 val += d_i * invBi;
00090 n /= base;
00091 invBi *= invBase;
00092 }
00093 return val;
00094 }
00095 inline double FoldedRadicalInverse(int n, int base) {
00096 double val = 0;
00097 double invBase = 1.f/base, invBi = invBase;
00098 int modOffset = 0;
00099 while (val + base * invBi != val) {
00100
00101 int digit = ((n+modOffset) % base);
00102 val += digit * invBi;
00103 n /= base;
00104 invBi *= invBase;
00105 ++modOffset;
00106 }
00107 return val;
00108 }
00109 inline float
00110 VanDerCorput(u_int n, u_int scramble = 0);
00111 inline float
00112 Sobol2(u_int n, u_int scramble = 0);
00113 inline float
00114 LarcherPillichshammer2(u_int n, u_int scramble = 0);
00115 inline void
00116 Sample02(u_int n,
00117 u_int scramble[2], float sample[2]);
00118 class Filter {
00119 public:
00120
00121 virtual ~Filter() { }
00122 Filter(float xw, float yw)
00123 : xWidth(xw), yWidth(yw), invXWidth(1.f/xw),
00124 invYWidth(1.f/yw) {
00125 }
00126 virtual float Evaluate(float x, float y) const = 0;
00127
00128 const float xWidth, yWidth;
00129 const float invXWidth, invYWidth;
00130 };
00131
00132 inline void Sample02(u_int n, u_int scramble[2],
00133 float sample[2]) {
00134 sample[0] = VanDerCorput(n, scramble[0]);
00135 sample[1] = Sobol2(n, scramble[1]);
00136 }
00137 inline float VanDerCorput(u_int n, u_int scramble) {
00138 n = (n << 16) | (n >> 16);
00139 n = ((n & 0x00ff00ff) << 8) | ((n & 0xff00ff00) >> 8);
00140 n = ((n & 0x0f0f0f0f) << 4) | ((n & 0xf0f0f0f0) >> 4);
00141 n = ((n & 0x33333333) << 2) | ((n & 0xcccccccc) >> 2);
00142 n = ((n & 0x55555555) << 1) | ((n & 0xaaaaaaaa) >> 1);
00143 n ^= scramble;
00144 return (float)n / (float)0x100000000LL;
00145 }
00146 inline float Sobol2(u_int n, u_int scramble) {
00147 for (u_int v = 1 << 31; n != 0; n >>= 1, v ^= v >> 1)
00148 if (n & 0x1) scramble ^= v;
00149 return (float)scramble / (float)0x100000000LL;
00150 }
00151 inline float
00152 LarcherPillichshammer2(u_int n, u_int scramble) {
00153 for (u_int v = 1 << 31; n != 0; n >>= 1, v |= v >> 1)
00154 if (n & 0x1) scramble ^= v;
00155 return (float)scramble / (float)0x100000000LL;
00156 }
00157 inline void LDShuffleScrambled1D(int nSamples,
00158 int nPixel, float *samples) {
00159 u_int scramble = RandomUInt();
00160 for (int i = 0; i < nSamples * nPixel; ++i)
00161 samples[i] = VanDerCorput(i, scramble);
00162 for (int i = 0; i < nPixel; ++i)
00163 Shuffle(samples + i * nSamples, nSamples, 1);
00164 Shuffle(samples, nPixel, nSamples);
00165 }
00166 inline void LDShuffleScrambled2D(int nSamples,
00167 int nPixel, float *samples) {
00168 u_int scramble[2] = { RandomUInt(), RandomUInt() };
00169 for (int i = 0; i < nSamples * nPixel; ++i)
00170 Sample02(i, scramble, &samples[2*i]);
00171 for (int i = 0; i < nPixel; ++i)
00172 Shuffle(samples + 2 * i * nSamples, nSamples, 2);
00173 Shuffle(samples, nPixel, 2 * nSamples);
00174 }
00175 #endif // PBRT_SAMPLING_H