00001 #ifndef FRESNEL_H_
00002 #define FRESNEL_H_
00003
00004 #include <complex>
00005
00006 namespace rcrt
00007 {
00008
00012 inline float fresnelTerm(float c, std::complex<float> n)
00013 {
00014 std::complex<float> g2 = n*n + c*c - 1.0f;
00015 float absg2 = abs(g2);
00016 float a = sqrt((absg2 + g2.real())/2.0f);
00017 float b = sqrt((absg2 - g2.real())/2.0f);
00018 float st = (1.0f-c*c)/c;
00019 float b2 = b * b;
00020 return 0.5*((a-c)*(a-c)+b2)/((a+c)*(a+c)+b2)*
00021 (1.0+((a-st)*(a-st)+b2)/((a+st)*(a+st)+b2));
00022 }
00023
00028 inline Vec3D snell(const Vec3D& wInc, const Vec3D& normal, const float& eta)
00029 {
00030 float cosI = wInc * normal;
00031 float cosT = 1.0 - (eta * eta) * (1.0 - cosI * cosI);
00032
00033 if (cosT <= 0.0f) {
00034 return wInc.reflect(normal);
00035 }
00036
00037 cosT = eta * cosI + sqrt(cosT);
00038
00039 return wInc * eta + normal * -cosT;
00040 }
00041
00051 inline float frRDielectric(const float& cosI, const float& cosT,
00052 const float& etaI, const float& etaT)
00053 {
00054 const float Rp = ((etaI * cosT) - (etaT * cosI)) / ((etaI * cosT) + (etaT * cosI));
00055 const float Rs = ((etaI * cosI) - (etaT * cosT)) / ((etaI * cosI) + (etaT * cosT));
00056 return (Rp*Rp + Rs*Rs) / 2.0f;
00057 }
00058
00068 inline float frTDielectric(const float& cosI, const float& cosT,
00069 const float& etaI, const float& etaT)
00070 {
00071 return 1-frRDielectric(cosI,cosT,etaI,etaT);
00072 }
00073
00074
00075 }
00076
00077 #endif