00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "pbrt.h"
00026 #include "geometry.h"
00027 #include "shape.h"
00028 #include "mc.h"
00029 #include "volume.h"
00030
00031 void ComputeStep1dCDF(float *f, int nSteps, float *c,
00032 float *cdf) {
00033
00034 int i;
00035 cdf[0] = 0.;
00036 for (i = 1; i < nSteps+1; ++i)
00037 cdf[i] = cdf[i-1] + f[i-1] / nSteps;
00038
00039 *c = cdf[nSteps];
00040 for (i = 1; i < nSteps+1; ++i)
00041 cdf[i] /= *c;
00042 }
00043 float SampleStep1d(float *f, float *cdf, float c,
00044 int nSteps, float u, float *pdf) {
00045
00046 float *ptr = std::lower_bound(cdf, cdf+nSteps+1, u);
00047 int offset = (int) (ptr-cdf-1);
00048
00049 u = (u - cdf[offset]) / (cdf[offset+1] - cdf[offset]);
00050 *pdf = f[offset] / c;
00051 return (offset + u) / nSteps;
00052 }
00053 void RejectionSampleDisk(float *x, float *y) {
00054 float sx, sy;
00055 do {
00056 sx = 1.f - 2.f * RandomFloat();
00057 sy = 1.f - 2.f * RandomFloat();
00058 } while (sx*sx + sy*sy > 1.f);
00059 *x = sx;
00060 *y = sy;
00061 }
00062 COREDLL Vector UniformSampleHemisphere(float u1, float u2) {
00063 float z = u1;
00064 float r = sqrtf(max(0.f, 1.f - z*z));
00065 float phi = 2 * M_PI * u2;
00066 float x = r * cosf(phi);
00067 float y = r * sinf(phi);
00068 return Vector(x, y, z);
00069 }
00070 COREDLL float UniformHemispherePdf(float theta, float phi) {
00071 return INV_TWOPI;
00072 }
00073 COREDLL Vector UniformSampleSphere(float u1, float u2) {
00074 float z = 1.f - 2.f * u1;
00075 float r = sqrtf(max(0.f, 1.f - z*z));
00076 float phi = 2.f * M_PI * u2;
00077 float x = r * cosf(phi);
00078 float y = r * sinf(phi);
00079 return Vector(x, y, z);
00080 }
00081 COREDLL float UniformSpherePdf() {
00082 return 1.f / (4.f * M_PI);
00083 }
00084 COREDLL void UniformSampleDisk(float u1, float u2,
00085 float *x, float *y) {
00086 float r = sqrtf(u1);
00087 float theta = 2.0f * M_PI * u2;
00088 *x = r * cosf(theta);
00089 *y = r * sinf(theta);
00090 }
00091 COREDLL void ConcentricSampleDisk(float u1, float u2,
00092 float *dx, float *dy) {
00093 float r, theta;
00094
00095 float sx = 2 * u1 - 1;
00096 float sy = 2 * u2 - 1;
00097
00098
00099 if (sx == 0.0 && sy == 0.0) {
00100 *dx = 0.0;
00101 *dy = 0.0;
00102 return;
00103 }
00104 if (sx >= -sy) {
00105 if (sx > sy) {
00106
00107 r = sx;
00108 if (sy > 0.0)
00109 theta = sy/r;
00110 else
00111 theta = 8.0f + sy/r;
00112 }
00113 else {
00114
00115 r = sy;
00116 theta = 2.0f - sx/r;
00117 }
00118 }
00119 else {
00120 if (sx <= sy) {
00121
00122 r = -sx;
00123 theta = 4.0f - sy/r;
00124 }
00125 else {
00126
00127 r = -sy;
00128 theta = 6.0f + sx/r;
00129 }
00130 }
00131 theta *= M_PI / 4.f;
00132 *dx = r*cosf(theta);
00133 *dy = r*sinf(theta);
00134 }
00135 COREDLL void UniformSampleTriangle(float u1, float u2,
00136 float *u, float *v) {
00137 float su1 = sqrtf(u1);
00138 *u = 1.f - su1;
00139 *v = u2 * su1;
00140 }
00141 COREDLL float UniformConePdf(float cosThetaMax) {
00142 return 1.f / (2.f * M_PI * (1.f - cosThetaMax));
00143 }
00144 Vector UniformSampleCone(float u1, float u2,
00145 float costhetamax) {
00146 float costheta = Lerp(u1, costhetamax, 1.f);
00147 float sintheta = sqrtf(1.f - costheta*costheta);
00148 float phi = u2 * 2.f * M_PI;
00149 return Vector(cosf(phi) * sintheta,
00150 sinf(phi) * sintheta,
00151 costheta);
00152 }
00153 COREDLL Vector UniformSampleCone(float u1, float u2, float costhetamax,
00154 const Vector &x, const Vector &y, const Vector &z) {
00155 float costheta = Lerp(u1, costhetamax, 1.f);
00156 float sintheta = sqrtf(1.f - costheta*costheta);
00157 float phi = u2 * 2.f * M_PI;
00158 return cosf(phi) * sintheta * x + sinf(phi) * sintheta * y +
00159 costheta * z;
00160 }
00161 COREDLL Vector SampleHG(const Vector &w, float g,
00162 float u1, float u2) {
00163 float costheta;
00164 if (fabsf(g) < 1e-3)
00165 costheta = 1.f - 2.f * u1;
00166 else {
00167 float sqrTerm = (1.f - g * g) /
00168 (1.f - g + 2.f * g * u1);
00169 costheta = (1.f + g * g - sqrTerm * sqrTerm) / (2.f * g);
00170 }
00171 float sintheta = sqrtf(max(0.f, 1.f-costheta*costheta));
00172 float phi = 2.f * M_PI * u2;
00173 Vector v1, v2;
00174 CoordinateSystem(w, &v1, &v2);
00175 return SphericalDirection(sintheta, costheta,
00176 phi, v1, v2, w);
00177 }
00178 COREDLL float HGPdf(const Vector &w, const Vector &wp,
00179 float g) {
00180 return PhaseHG(w, wp, g);
00181 }