BSDF.h
Go to the documentation of this file.00001 /**<!--------------------------------------------------------------------> 00002 @class BSDF 00003 @author Travis Fischer (fisch0920@gmail.com) 00004 @author Matthew Jacobs (jacobs.mh@gmail.com) 00005 @date Fall 2008 00006 00007 @brief 00008 Abstract representation of a BSDF defined at a single point on a 00009 surface in 3-space. 00010 00011 A BSDF (or Bidirectional Scattering Distribution Function) is a function 00012 defining the fraction of light propagated after hitting a surface in a 00013 given exitent direction, wo, from a given incident direction, wi. It 00014 represents the observed radiance leaving in direction wo, per unit of 00015 irradiance arriving from wi. A BSDF is commonly denoted by the notation 00016 fs(wi->wo). 00017 It is much more common in computer graphics to hear one speak about 00018 BRDFs (or Bidirectional Reflectance Distribution Functions), the difference 00019 being that BSDFs are defined over the entire sphere of solid angles and 00020 therefore include transmission (transparency), whereas BRDFs are defined 00021 only on the positive hemisphere at a surface point with respect to its 00022 local geometric normal. BRDFs represent a subset of allowable BSDFs, and 00023 they suffice in simulating the majority of real world materials. The 00024 added complexity / generality of BSDFs, however, is important to any 00025 physically based rendering engine such as Milton. A BRDF is commonly 00026 denoted by fr(wi->wo). 00027 00028 Physically valid BRDFs have several basic properties or consraints, 00029 namely reciprocity and conservation of energy. 00030 Reciprocity means that BRDFs are symmetric: fr(wi->wo) = fr(wo->wi). 00031 For this reason, it is common to make the symmetric explicit in the notation 00032 by instead writing fr(wi<->wo) in the case of BRDFs or fs(wi<->wo) in the 00033 case of BSDFs. 00034 Conservation of energy states that a surface should not reflect more 00035 energy than it receives. Formally this can be stated as the integral of 00036 fr(wi->wo) over the positive hemisphere at any point with respect to a 00037 projected solid angle measure has to be less than or equal to one for 00038 all possible incident vectors, wi. 00039 00040 @htmlonly 00041 Example usage: 00042 <pre><code> 00043 SurfacePoint pt; 00044 const real_t t = m_scene->getIntersection(ray, pt); 00045 00046 // lazily initialize SurfacePoint and return if no intersection 00047 if (!pt.init(ray, t)) 00048 return; // ray didn't hit anything (t == INFINITY) 00049 00050 // sample the BSDF for an exitant direction 00051 const Event &event = pt.bsdf->sample(); 00052 const Vector3 &wo = event; 00053 00054 if (wo == Vector3::zero()) 00055 return; // invalid exitant direction 00056 00057 // evaluate BSDF in the given exitant direction and divide by probability 00058 // with which we sampled that direction 00059 const real_t pdf = pt.bsdf->getPdf(event); 00060 const SpectralSampleSet &fs = pt.bsdf->getBSDF(wo) / pdf; 00061 00062 // ... trace another ray in direction 'wo' ... 00063 </code></pre> 00064 @endhtmlonly 00065 <!-------------------------------------------------------------------->**/ 00066 00067 #ifndef BSDF_H_ 00068 #define BSDF_H_ 00069 00070 #include <core/SurfacePoint.h> 00071 #include <utils/SpectralSampleSet.h> 00072 #include <stats/Sampler.h> 00073 #include <shapes/Shape.h> 00074 #include <common/image/Image.h> 00075 00076 class Material; 00077 00078 class BSDF : public Sampler, public SSEAligned { 00079 public: 00080 ///@name Constructors 00081 //@{----------------------------------------------------------------- 00082 00083 inline explicit BSDF(SurfacePoint &pt, Material *parent = NULL) 00084 : Sampler(), m_wi(1, 0, 0), m_pt(pt), m_parent(parent) 00085 { } 00086 00087 virtual ~BSDF() 00088 { } 00089 00090 00091 //@}----------------------------------------------------------------- 00092 ///@name Initialization 00093 //@{----------------------------------------------------------------- 00094 00095 /** 00096 * @brief 00097 * Performs any initialization that may be necessary before beginning 00098 * to sample this BSDF 00099 * 00100 * @note default implementation is empty 00101 */ 00102 virtual void init() 00103 { } 00104 00105 00106 //@}----------------------------------------------------------------- 00107 ///@name Main usage interface 00108 //@{----------------------------------------------------------------- 00109 00110 /** 00111 * @brief 00112 * Sets the incident vector, wi, for this BSDF. All BSDF sampling 00113 * is with respect to the current value of wi. 00114 */ 00115 virtual void setWi(const Vector3 &wi) { 00116 m_wi = wi; 00117 } 00118 00119 /** 00120 * @brief 00121 * Samples an exitent vector at the given surface point 00122 * 00123 * @returns the sampled vector as a Vector3 wrapped in an Event object 00124 * @note returns Vector3::zero() if no exitent vector was sampled 00125 * (to model a certain probability of absorption, for instance) 00126 * 00127 * @htmlonly 00128 * Example usage: 00129 * <pre><code> 00130 * const Event &event = bsdf.sample(); 00131 * const Vector3 &wo = event.getValue<Vector3>(); 00132 * const real_t pd = bsdf.getPdf(event); // p(x) probability 00133 * const SpectralSampleSet &fs = bsdf.getBSDF(wo); // f(x) reflectivity 00134 * </code></pre> 00135 * @endhtmlonly 00136 */ 00137 virtual Event sample() = 0; 00138 00139 /** 00140 * @returns the probability density of having sampled the given out 00141 * out vector @p event with respect to whatever underlying sampling 00142 * strategy is being used to sample the BSDF 00143 * 00144 * @note probability density is assumed to be with respect to projected 00145 * solid angle (the conversion from solid angle to projected solid 00146 * angle involves dividing the solid angle density by the absolute 00147 * value of the cosine of the angle between the local surface normal 00148 * and the exitant vector in @p event) 00149 */ 00150 virtual real_t getPdf(const Event &event) = 0; 00151 00152 /** 00153 * @brief 00154 * Evaluates the spectral BSDF at the given surface point with respect 00155 * to the out vector, 'wo', at the underlying surface point and given 00156 * incident vector, 'wi' 00157 * 00158 * @returns the spectral radiance leaving in direction wo, per unit of 00159 * irradiance arriving from wi (unitless fraction in [0, 1]) 00160 * 00161 * @note uses the currently set m_wi for the incident vector 00162 */ 00163 inline SpectralSampleSet getBSDF(const Vector3 &wo) { 00164 return getBSDF(m_wi, wo); 00165 } 00166 00167 /** 00168 * @brief 00169 * Evaluates the spectral BSDF at the given surface point with respect 00170 * to the out vector, 'wo', at the underlying surface point and given 00171 * incident vector, 'wi' 00172 * 00173 * @returns the spectral radiance leaving in direction wo, per unit of 00174 * irradiance arriving from wi (unitless fraction in [0, 1]) 00175 */ 00176 virtual SpectralSampleSet getBSDF(const Vector3 &wi, 00177 const Vector3 &wo) = 0; 00178 00179 /** 00180 * @returns true iff this BSDF is non-zero over a set of solid angles 00181 * with measure zero (measured with respect to solid angle) 00182 * 00183 * @note a perfectly specular material has a dirac distribution for its 00184 * reflectance, and therefore needs special consideration when 00185 * sampling the BRDF for simulation purposes 00186 * @note the default implementation returns false because perfectly 00187 * specular surfaces don't occur that often in real life, though they 00188 * abound in computer graphics (due to their ease of simulation) 00189 */ 00190 inline bool isSpecular() const { 00191 Event e; 00192 return isSpecular(e); 00193 } 00194 00195 /** 00196 * @returns true iff this BSDF is non-zero over a set of solid angles 00197 * with measure zero (measured with respect to solid angle) 00198 * 00199 * @note a perfectly specular material has a dirac distribution for its 00200 * reflectance, and therefore needs special consideration when 00201 * sampling the BRDF for simulation purposes 00202 * @note the default implementation returns false because perfectly 00203 * specular surfaces don't occur that often in real life, though they 00204 * abound in computer graphics (due to their ease of simulation) 00205 * @note implementations are free to use the given Event's metadata 00206 * to determine whether or not it represents a specular event 00207 */ 00208 virtual bool isSpecular(Event &/* event unused*/) const { 00209 return false; 00210 } 00211 00212 /** 00213 * @brief 00214 * Sets up OpenGL material state (color properties, etc.) to enable 00215 * a crude/fast preview of geometry to which this BSDF is applied 00216 * 00217 * @note default implementation sets the current glColor 00218 * @param shape is the Shape which this BSDF will preview itself on 00219 */ 00220 virtual void preview(Shape *shape); 00221 00222 00223 //@}----------------------------------------------------------------- 00224 ///@name Accessors/Mutators 00225 //@{----------------------------------------------------------------- 00226 00227 /** 00228 * @returns the SurfacePoint at which this BSDF instance is defined 00229 */ 00230 inline SurfacePoint &getSurfacePoint() { 00231 return m_pt; 00232 } 00233 00234 /** 00235 * @returns the current incident vector, wi, for which this BSDF will 00236 * be sampled 00237 */ 00238 inline const Vector3 &getWi() const { 00239 return m_wi; 00240 } 00241 00242 /** 00243 * @returns the parent Material which instantiated this BSDF 00244 * 00245 * @note the parent Material is also a PropertyMap and contians all 00246 * key-value inputs to this BSDF 00247 */ 00248 inline Material *getParent() { 00249 return m_parent; 00250 } 00251 00252 /** 00253 * @returns the perfect specularly reflected direction given the current 00254 * incident vector, wi, which is defined to be wi rotated about the 00255 * local surface normal 00256 * 00257 * @see also Vector::reflectVector 00258 */ 00259 inline Vector3 getSpecularReflection() const { 00260 return m_wi.reflectVector(m_pt.normalS); 00261 } 00262 00263 00264 //@}----------------------------------------------------------------- 00265 00266 protected: 00267 Vector3 m_wi; 00268 SurfacePoint &m_pt; 00269 Material *m_parent; 00270 }; 00271 00272 #endif // BSDF_H_ 00273
Generated on 28 Feb 2009 for Milton by
1.5.6