00001 /*************************************************************************** 00002 * Copyright (C) 1998-2008 by authors (see AUTHORS.txt ) * 00003 * * 00004 * This file is part of LuxRender. * 00005 * * 00006 * Lux Renderer is free software; you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation; either version 3 of the License, or * 00009 * (at your option) any later version. * 00010 * * 00011 * Lux Renderer is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License * 00017 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 00018 * * 00019 * This project is based on PBRT ; see http://www.pbrt.org * 00020 * Lux Renderer website : http://www.luxrender.net * 00021 ***************************************************************************/ 00022 00023 // fresneldielectric.cpp* 00024 #include "fresneldielectric.h" 00025 #include "color.h" 00026 #include "spectrum.h" 00027 #include "spectrumwavelengths.h" 00028 #include "mc.h" 00029 #include "sampling.h" 00030 #include <stdarg.h> 00031 00032 #include <boost/thread/tss.hpp> 00033 00034 using namespace lux; 00035 00036 extern boost::thread_specific_ptr<SpectrumWavelengths> thread_wavelengths; 00037 00038 SWCSpectrum FresnelDielectric::Evaluate(float cosi) const { 00039 // Compute Fresnel reflectance for dielectric 00040 cosi = Clamp(cosi, -1.f, 1.f); 00041 // Compute indices of refraction for dielectric 00042 bool entering = cosi > 0.; 00043 float ei = eta_i, et = eta_t; 00044 00045 if(cb != 0.) { 00046 // Handle dispersion using cauchy formula 00047 float w = thread_wavelengths->SampleSingle(); 00048 et = eta_t + (cb * 1000000) / (w*w); 00049 } 00050 00051 if (!entering) 00052 swap(ei, et); 00053 // Compute _sint_ using Snell's law 00054 float sint = ei/et * sqrtf(max(0.f, 1.f - cosi*cosi)); 00055 if (sint > 1.) { 00056 // Handle total internal reflection 00057 return 1.; 00058 } 00059 else { 00060 float cost = sqrtf(max(0.f, 1.f - sint*sint)); 00061 return FrDiel(fabsf(cosi), cost, ei, et); 00062 } 00063 } 00064