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 "specularreflection.h"
00025 #include "spectrum.h"
00026 #include "spectrumwavelengths.h"
00027 #include "fresnel.h"
00028
00029 using namespace lux;
00030
00031
00032 inline void PhaseDifference(const TsPack *tspack, const Vector &wo, float film, float filmindex, SWCSpectrum *const Pd) {
00033 const float swo = SinTheta(wo);
00034 const float s = sqrtf(filmindex * filmindex - swo * swo);
00035 for(int i=0; i<WAVELENGTH_SAMPLES; i++) {
00036 const float pd = (4.f * M_PI * film / tspack->swl->w[i]) * s + M_PI;
00037 const float cpd = cosf(pd);
00038 Pd->c[i] *= cpd*cpd;
00039 }
00040 }
00041
00042 bool SpecularReflection::Sample_f(const TsPack *tspack, const Vector &wo,
00043 Vector *wi, float u1, float u2, SWCSpectrum *const f_, float *pdf, float *pdfBack, bool reverse) const {
00044
00045 *wi = Vector(-wo.x, -wo.y, wo.z);
00046 *pdf = 1.f;
00047 if (pdfBack)
00048 *pdfBack = 1.f;
00049 fresnel->Evaluate(tspack, CosTheta(wo), f_);
00050 if(film > 0.f) PhaseDifference(tspack, wo, film, filmindex, f_);
00051 *f_ *= R;
00052 *f_ /= fabsf(CosTheta(wo));
00053 return true;
00054 }
00055 float SpecularReflection::Weight(const TsPack *tspack, const Vector &wo) const
00056 {
00057 SWCSpectrum F;
00058 fresnel->Evaluate(tspack, CosTheta(wo), &F);
00059 return F.Filter(tspack) / fabsf(CosTheta(wo));
00060 }
00061
00062 bool ArchitecturalReflection::Sample_f(const TsPack *tspack, const Vector &wo,
00063 Vector *wi, float u1, float u2, SWCSpectrum *const f_, float *pdf, float *pdfBack, bool reverse) const
00064 {
00065 if (wo.z <= 0.f) {
00066 *pdf = 0.f;
00067 if (pdfBack)
00068 *pdfBack = 0.f;
00069 return false;
00070 }
00071 return SpecularReflection::Sample_f(tspack, wo, wi, u1, u2, f_, pdf, pdfBack, reverse);
00072 }
00073 float ArchitecturalReflection::Weight(const TsPack *tspack, const Vector &wo) const
00074 {
00075 if (wo.z <= 0.f)
00076 return 0.f;
00077 return SpecularReflection::Weight(tspack, wo);
00078 }