DielectricBSDF.cpp
Go to the documentation of this file.00001 /**<!--------------------------------------------------------------------> 00002 @file DielectricBSDF.cpp 00003 @author Travis Fischer (fisch0920@gmail.com) 00004 @author Matthew Jacobs (jacobs.mh@gmail.com) 00005 @date Fall 2008 00006 00007 @brief 00008 Wavelength-dependent, thin dielectric BSDF defined at a single point on 00009 a surface in 3-space. The opacity input controls the transmittance versus 00010 reflectance of different wavelengths. A pure specular mirror may be obtained 00011 by creating a dielectric BSDF with zero opacity. Conversely, a purely 00012 transparent surface may be obtained by creating a dielectric with full 00013 opacity. Note that a completely transparent surface will still reflect some 00014 light (in proportion to Fresnel's Laws) because refraction is undefined past 00015 a critical angle when light is traveling between a lighter and denser 00016 medium. When this happens, some light is reflected regardless of the opacity 00017 parameter, and this is typically known as total internal reflection. 00018 00019 @param 00020 opacity - SpectralSampleSet which specifies the transmittance of the 00021 material 00022 00023 @param 00024 ks - SpectralSampleSet which scales / attenuates the overall 00025 reflectance of the material (specular albedo) 00026 <!-------------------------------------------------------------------->**/ 00027 00028 #include "DielectricBSDF.h" 00029 #include <IndexOfRefraction.h> 00030 #include <Material.h> 00031 #include <Fresnel.h> 00032 #include <Random.h> 00033 00034 void DielectricBSDF::init() { 00035 m_ior = m_parent->getSpectralSampleSet("ior", IndexOfRefraction::AIR, m_pt); 00036 00037 m_transparency = m_parent->getSpectralSampleSet("transparency", 1.0, m_pt); 00038 m_avgTransparency = m_transparency.getAverage(); 00039 } 00040 00041 Event DielectricBSDF::sample() { 00042 const Vector3 &N = 00043 (m_pt.normal.dot(m_wi) > 0 ? -m_pt.normalS : m_pt.normalS); 00044 const unsigned index = Random::sampleInt(0, m_ior.getN()); 00045 const real_t ior = m_ior[index].value; 00046 const Vector3 &wt = m_wi.refractVector(m_pt.normalS, m_pt.ior1, ior); 00047 00048 if (wt != Vector3::zero()) { 00049 const real_t Fr = Fresnel::getFr(m_wi, m_pt.normalS, m_pt.ior1, ior); 00050 ASSERT(Fr >= 0 && Fr <= 1); 00051 00052 // attenuate normal Fresnel transmission coefficient, Fs, by the average 00053 // transparency of the surface 00054 const real_t Fs = m_avgTransparency * (1 - Fr); 00055 ASSERT(Fs >= 0 && Fs <= 1); 00056 00057 // refract with probability Fs 00058 if (Random::sample() < Fs) 00059 return Event(wt, this, index); 00060 } 00061 00062 return Event(m_wi.reflectVector(N), this); 00063 } 00064 00065 real_t DielectricBSDF::getPdf(const Event &event) { 00066 const Vector3 &wo = event.getValue<const Vector3&>(); 00067 const Vector3 &N = 00068 (m_pt.normal.dot(m_wi) > 0 ? -m_pt.normalS : m_pt.normalS); 00069 00070 if (wo.dot(N) < 0) { 00071 //const Vector3 &wt = m_wi.refractVector(m_pt.normalS, m_pt.ior1, m_pt.ior2); 00072 real_t n = 0; 00073 for(unsigned i = m_ior.getN(); i--;) { 00074 const Vector3 &wt = m_wi.refractVector(m_pt.normalS, m_pt.ior1, m_ior[i].value); 00075 00076 n += (wo == wt); 00077 } 00078 00079 return n / m_ior.getN(); 00080 //return (wo == wt ? 1 : 0); 00081 } 00082 00083 return (wo == m_wi.reflectVector(N) ? 1 : 0); 00084 } 00085 00086 SpectralSampleSet DielectricBSDF::getBSDF(const Vector3 &wi, const Vector3 &wo) { 00087 const SpectralSampleSet &ks = 00088 m_parent->getSpectralSampleSet("ks", SpectralSampleSet::fill(1.0), m_pt); 00089 const Vector3 &N = 00090 (m_pt.normal.dot(wi) > 0 ? -m_pt.normalS : m_pt.normalS); 00091 00092 if (wo.dot(N) < 0) { 00093 SpectralSampleSet s(m_ior); 00094 for(unsigned i = m_ior.getN(); i--;) { 00095 const Vector3 &wt = wi.refractVector(m_pt.normalS, m_pt.ior1, m_ior[i].value); 00096 00097 s[i].value = (wo == wt); 00098 } 00099 00100 return ks * s; 00101 //return ks * (wo == wt); 00102 } 00103 00104 return ks * (wo == wi.reflectVector(N)); 00105 } 00106
Generated on 28 Feb 2009 for Milton by
1.5.6