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 "fresneldielectric.h"
00025 #include "spectrum.h"
00026 #include "spectrumwavelengths.h"
00027
00028 using namespace lux;
00029
00030 void FresnelDielectric::Evaluate(const TsPack *tspack, float cosi, SWCSpectrum *const f) const {
00031 if (cb != 0.f && !tspack->swl->single) {
00032 SWCSpectrum eta = SWCSpectrum(tspack->swl->w);
00033 eta *= eta;
00034 eta = SWCSpectrum(eta_t) + SWCSpectrum(cb) / eta;
00035 SWCSpectrum cost(sqrtf(max(0.f, 1.f - cosi * cosi)));
00036 if (cosi > 0.f)
00037 cost /= eta;
00038 else
00039 cost *= eta;
00040 cost.Clamp(0.f, 1.f);
00041 cost = (SWCSpectrum(1.f) - cost * cost).Sqrt();
00042 FrDiel2(fabsf(cosi), cost, eta, f);
00043 } else {
00044
00045 cosi = Clamp(cosi, -1.f, 1.f);
00046
00047 bool entering = cosi > 0.;
00048 float et = eta_t;
00049
00050
00051 if(cb != 0.f) {
00052 const float w = tspack->swl->w[tspack->swl->single_w];
00053 et += cb / (w * w);
00054 }
00055
00056
00057 const float sint = (entering ? 1.f / et : et) *
00058 sqrtf(max(0.f, 1.f - cosi * cosi));
00059
00060 if (sint >= 1.f)
00061 *f = SWCSpectrum(1.f);
00062 else
00063 FrDiel(fabsf(cosi), sqrtf(max(0.f, 1.f - sint * sint)),
00064 1.f, et, f);
00065 }
00066 }
00067
00068 float FresnelDielectric::Index(const TsPack *tspack) const
00069 {
00070 const float *w = tspack->swl->w;
00071 if (tspack->swl->single)
00072 return (eta_t + cb / (w[tspack->swl->single_w] * w[tspack->swl->single_w]));
00073 const float i[4] = {eta_t + cb / (w[0] * w[0]),
00074 eta_t + cb / (w[1] * w[1]),
00075 eta_t + cb / (w[2] * w[2]),
00076 eta_t + cb / (w[3] * w[3])};
00077 return SWCSpectrum(i).Filter(tspack);
00078 }