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 "anisotropic.h"
00025 #include "color.h"
00026 #include "spectrum.h"
00027 #include "mc.h"
00028 #include "sampling.h"
00029 #include <stdarg.h>
00030
00031 using namespace lux;
00032
00033 void Anisotropic::Sample_f(const Vector &wo, Vector *wi,
00034 float u1, float u2, float *pdf) const {
00035
00036 float phi, costheta;
00037 if (u1 < .25f) {
00038 sampleFirstQuadrant(4.f * u1, u2, &phi, &costheta);
00039 } else if (u1 < .5f) {
00040 u1 = 4.f * (.5f - u1);
00041 sampleFirstQuadrant(u1, u2, &phi, &costheta);
00042 phi = M_PI - phi;
00043 } else if (u1 < .75f) {
00044 u1 = 4.f * (u1 - .5f);
00045 sampleFirstQuadrant(u1, u2, &phi, &costheta);
00046 phi += M_PI;
00047 } else {
00048 u1 = 4.f * (1.f - u1);
00049 sampleFirstQuadrant(u1, u2, &phi, &costheta);
00050 phi = 2.f * M_PI - phi;
00051 }
00052 float sintheta = sqrtf(max(0.f, 1.f - costheta*costheta));
00053 Vector H = SphericalDirection(sintheta, costheta, phi);
00054 if (Dot(wo, H) < 0.f) H = -H;
00055
00056 *wi = -wo + 2.f * Dot(wo, H) * H;
00057
00058 float anisotropic_pdf = D(H) / (4.f * Dot(wo, H));
00059 *pdf = anisotropic_pdf;
00060 }
00061 void Anisotropic::sampleFirstQuadrant(float u1, float u2,
00062 float *phi, float *costheta) const {
00063 if (ex == ey)
00064 *phi = M_PI * u1 * 0.5f;
00065 else
00066 *phi = atanf(sqrtf((ex+1)/(ey+1)) *
00067 tanf(M_PI * u1 * 0.5f));
00068 float cosphi = cosf(*phi), sinphi = sinf(*phi);
00069 *costheta = powf(u2, 1.f/(ex * cosphi * cosphi +
00070 ey * sinphi * sinphi + 1));
00071 }
00072 float Anisotropic::Pdf(const Vector &wo,
00073 const Vector &wi) const {
00074 Vector H = Normalize(wo + wi);
00075
00076 float anisotropic_pdf = D(H) / (4.f * Dot(wo, H));
00077 return anisotropic_pdf;
00078 }
00079