Mitsuba Renderer  0.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
bsdf.h
Go to the documentation of this file.
1 /*
2  This file is part of Mitsuba, a physically based rendering system.
3 
4  Copyright (c) 2007-2014 by Wenzel Jakob and others.
5 
6  Mitsuba is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License Version 3
8  as published by the Free Software Foundation.
9 
10  Mitsuba is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #if !defined(__MITSUBA_RENDER_BSDF_H_)
21 #define __MITSUBA_RENDER_BSDF_H_
22 
23 #include <mitsuba/core/cobject.h>
24 #include <mitsuba/core/frame.h>
26 #include <mitsuba/render/common.h>
27 #include <mitsuba/render/shader.h>
28 
30 
31 /**
32  * \brief This data structured contains all information
33  * that is required to sample or query a BSDF.
34  *
35  * \sa BSDF::f()
36  * \sa BSDF::sample()
37  * \ingroup librender
38  * \ingroup libpython
39  */
41 public:
42  /**
43  * \brief Given a surface interaction and an incident direction,
44  * construct a query record which can be used to sample an outgoing
45  * direction.
46  *
47  * By default, all components will be sampled irregardless of
48  * what measure they live on. For convenience, this function
49  * uses the local incident direction vector contained in the
50  * supplied intersection record. The mode of transport is
51  * set to \ref ERadiance -- the \ref mode fie
52  *
53  * \param its
54  * An reference to the underlying intersection record
55  *
56  * \param sampler
57  * A source of (pseudo-) random numbers. Note that this sampler
58  * is only used when the scattering model for some reason needs
59  * more than the two unformly distributed numbers supplied in
60  * the \ref BSDF::sample() methods
61  *
62  * \param mode
63  * The transported mode (\ref ERadiance or \ref EImportance)
64  */
65  explicit inline BSDFSamplingRecord(const Intersection &its, Sampler *sampler,
66  ETransportMode mode = ERadiance);
67 
68  /**
69  * \brief Given a surface interaction an an incident/exitant direction
70  * pair (wi, wo), create a query record to evaluate the BSDF or its
71  * sampling density.
72  *
73  * For convenience, this function uses the local incident direction
74  * vector contained in the supplied intersection record.
75  *
76  * \param its
77  * An reference to the underlying intersection record
78  * \param wo
79  * An outgoing direction in local coordinates. This should
80  * be a normalized direction vector that points \a away from
81  * the scattering event.
82  * \param mode
83  * The transported mode (\ref ERadiance or \ref EImportance)
84  */
85  inline BSDFSamplingRecord(const Intersection &its, const Vector &wo,
86  ETransportMode mode = ERadiance);
87 
88  /**
89  * \brief Given a surface interaction an an incident/exitant direction
90  * pair (wi, wo), create a query record to evaluate the BSDF or its
91  * sampling density.
92  *
93  * \param its
94  * An reference to the underlying intersection record
95  * \param wi
96  * An incident direction in local coordinates. This should
97  * be a normalized direction vector that points \a away from
98  * the scattering event.
99  * \param wo
100  * An outgoing direction in local coordinates. This should
101  * be a normalized direction vector that points \a away from
102  * the scattering event.
103  * \param mode
104  * The transported mode (\ref ERadiance or \ref EImportance)
105  *
106  */
107  inline BSDFSamplingRecord(const Intersection &its,
108  const Vector &wi, const Vector &wo,
109  ETransportMode mode = ERadiance);
110 
111  /**
112  * \brief Reverse the direction of light transport in the record
113  *
114  * This function essentially swaps \c wi and \c wo and adjusts
115  * \c mode appropriately, so that non-symmetric scattering
116  * models can be queried in the reverse direction.
117  */
118  inline void reverse();
119 
120  /// Return a string representation
121  std::string toString() const;
122 public:
123  /// Reference to the underlying surface interaction
125 
126  /**
127  * \brief Pointer to a \ref Sampler instance (optional).
128  *
129  * Some BSDF implementations can significantly improve
130  * the quality of their importance sampling routines
131  * when having access to extra random numbers. This
132  * attribute provides a means of providing this
133  * capability to the BSDF.
134  */
136 
137  /**
138  * \brief Normalized incident direction in local coordinates
139  *
140  * Mitsuba uses the convention that \c wi and \c wo
141  * point away from the scattering event
142  */
144 
145  /**
146  * \brief Normalized outgoing direction in local coordinates
147  *
148  * Mitsuba uses the convention that \c wi and \c wo
149  * point away from the scattering event
150  */
152 
153  /// Relative index of refraction in the sampled direction
155 
156  /** \brief Transported mode (radiance or importance)
157  *
158  * This information is required for rendering with non-reciprocal
159  * BSDFs such as transmission through a dielectric material
160  */
162 
163  /**
164  * \brief Bit mask containing the requested BSDF component types that
165  * should be sampled/evaluated.
166  *
167  * Set to \c BSDF::EAll by default. After sampling has been performed,
168  * the component type is stored inside \ref sampledType.
169  *
170  * \sa BSDF::EBSDFType
171  */
172  unsigned int typeMask;
173 
174  /**
175  * \brief Integer value specifying the requested BSDF component index that
176  * should be sampled/evaluated (for multi-lobed BSDFs).
177  *
178  * After sampling has been performed, the component index is stored
179  * inside \ref sampledComponent.
180  */
182 
183  /**
184  * \brief Stores the component type that was sampled by \ref BSDF::sample()
185  * \sa BSDF::EBSDFType
186  */
187  unsigned int sampledType;
188 
189  /**
190  * \brief Stores the component index that was sampled by \ref BSDF::sample()
191  */
193 };
194 
195 
196 /**
197  * \brief Abstract %BSDF base-class.
198  *
199  * This class implements an abstract interface to all BSDF plugins in Mitsuba.
200  * It exposes functions for evaluating and sampling the model, and it allows
201  * querying the probability density of the sampling method. Smooth
202  * two-dimensional density functions, as well as degenerate one-dimensional
203  * and discrete densities are all handled within the same framework.
204  *
205  * For improved flexibility with respect to the various rendering algorithms,
206  * this class can sample and evaluate a complete BSDF, but it also allows to
207  * pick and choose individual components of multi-lobed BSDFs based on their
208  * properties and component indices. This selection is specified using a
209  * special record that is provided along with every query.
210  *
211  * \ref BSDFSamplingRecord.
212  * \ingroup librender
213  * \ingroup libpython
214  */
216 public:
217  /**
218  * \brief This list of flags is used to classify the different
219  * types of lobes that are implemented in a BSDF instance.
220  *
221  * They are also useful for picking out individual components
222  * by setting combinations in \ref BSDFSamplingRecord::typeMask.
223  */
224  enum EBSDFType {
225  // =============================================================
226  // BSDF lobe types
227  // =============================================================
228 
229  /// 'null' scattering event, i.e. particles do not undergo deflection
230  ENull = 0x00001,
231  /// Ideally diffuse reflection
232  EDiffuseReflection = 0x00002,
233  /// Ideally diffuse transmission
234  EDiffuseTransmission = 0x00004,
235  /// Glossy reflection
236  EGlossyReflection = 0x00008,
237  /// Glossy transmission
238  EGlossyTransmission = 0x00010,
239  /// Reflection into a discrete set of directions
240  EDeltaReflection = 0x00020,
241  /// Transmission into a discrete set of directions
242  EDeltaTransmission = 0x00040,
243  /// Reflection into a 1D space of directions
244  EDelta1DReflection = 0x00080,
245  /// Transmission into a 1D space of directions
246  EDelta1DTransmission = 0x00100,
247 
248  // =============================================================
249  //! Other lobe attributes
250  // =============================================================
251  /// The lobe is not invariant to rotation around the normal
252  EAnisotropic = 0x01000,
253  /// The BSDF depends on the UV coordinates
254  ESpatiallyVarying = 0x02000,
255  /// Flags non-symmetry (e.g. transmission in dielectric materials)
256  ENonSymmetric = 0x04000,
257  /// Supports interactions on the front-facing side
258  EFrontSide = 0x08000,
259  /// Supports interactions on the back-facing side
260  EBackSide = 0x10000,
261  /// Uses extra random numbers from the supplied sampler instance
262  EUsesSampler = 0x20000
263  };
264 
265  /// Convenient combinations of flags from \ref EBSDFType
267  /// Any reflection component (scattering into discrete, 1D, or 2D set of directions)
268  EReflection = EDiffuseReflection | EDeltaReflection
269  | EDelta1DReflection | EGlossyReflection,
270  /// Any transmission component (scattering into discrete, 1D, or 2D set of directions)
271  ETransmission = EDiffuseTransmission | EDeltaTransmission
272  | EDelta1DTransmission | EGlossyTransmission | ENull,
273  /// Diffuse scattering into a 2D set of directions
274  EDiffuse = EDiffuseReflection | EDiffuseTransmission,
275  /// Non-diffuse scattering into a 2D set of directions
276  EGlossy = EGlossyReflection | EGlossyTransmission,
277  /// Scattering into a 2D set of directions
278  ESmooth = EDiffuse | EGlossy,
279  /// Scattering into a discrete set of directions
280  EDelta = ENull | EDeltaReflection | EDeltaTransmission,
281  /// Scattering into a 1D space of directions
282  EDelta1D = EDelta1DReflection | EDelta1DTransmission,
283  /// Any kind of scattering
284  EAll = EDiffuse | EGlossy | EDelta | EDelta1D
285  };
286 
287  /// Return the number of components of this BSDF
288  inline int getComponentCount() const {
289  return (int) m_components.size();
290  }
291 
292  /**
293  * \brief Return a listing of this BSDF's component types and
294  * properties, combined using binary OR.
295  * \sa EBSDFType
296  */
297  inline unsigned int getType() const {
298  return m_combinedType;
299  }
300 
301  /**
302  * Returns the classification flags of a specific component
303  * \sa EBSDFType
304  */
305  inline unsigned int getType(int component) const {
306  return m_components[component];
307  }
308 
309  /**
310  * \brief Return the measure corresponding to a particular
311  * component type
312  */
313  inline static EMeasure getMeasure(unsigned int componentType) {
314  if (componentType & ESmooth) {
315  return ESolidAngle;
316  } else if (componentType & EDelta) {
317  return EDiscrete;
318  } else if (componentType & EDelta1D) {
319  return ELength;
320  } else {
321  Log(EError, "getMeasure(): Invalid component type!");
322  return ESolidAngle; // will never be reached
323  }
324  }
325 
326  /// Test whether this BSDF contains a certain type of component
327  inline bool hasComponent(unsigned int type) const {
328  return (type & m_combinedType) != 0;
329  }
330 
331  /// Return whether this BSDF makes use of ray differentials
332  inline bool usesRayDifferentials() const {
333  return m_usesRayDifferentials;
334  }
335 
336  /// Return the diffuse reflectance value (if any)
337  virtual Spectrum getDiffuseReflectance(const Intersection &its) const;
338 
339  /// Return the specular reflectance value (if any)
340  virtual Spectrum getSpecularReflectance(const Intersection &its) const {
341  return Spectrum(0.0f);
342  }
343 
344  /**
345  * \brief Sample the BSDF and return the importance weight (i.e. the
346  * value of the BSDF divided by the probability density of the sample).
347  *
348  * When the probability density is not explicitly required, this function
349  * should be preferred, since it is potentially faster by making use of
350  * cancellations during the division.
351  *
352  * If a component mask or a specific component index is specified, the
353  * sample is drawn from the matching component, if it exists. Depending
354  * on the provided transport type, either the BSDF or its adjoint version
355  * is used.
356  *
357  * \param bRec A BSDF query record
358  * \param sample A uniformly distributed sample on \f$[0,1]^2\f$
359  *
360  * \return The BSDF value divided by the probability density of the sample
361  * sample (multiplied by the cosine foreshortening factor when a
362  * non-delta component is sampled) A zero spectrum means that
363  * sampling failed.
364  *
365  * \remark This function is not exposed by the Python API. See the other
366  * sample function instead.
367  *
368  */
369  virtual Spectrum sample(BSDFSamplingRecord &bRec, const Point2 &sample) const = 0;
370 
371  /**
372  * \brief Sample the BSDF and return the probability density \a and the
373  * importance weight of the sample (i.e. the value of the BSDF divided
374  * by the probability density)
375  *
376  * If a component mask or a specific component index is specified, the
377  * sample is drawn from the matching component, if it exists. Depending
378  * on the provided transport type, either the BSDF or its adjoint version
379  * is used.
380  *
381  * When sampling a continuous/non-delta component, this method also
382  * multiplies by the cosine foreshorening factor with respect to the
383  * sampled direction.
384  *
385  * \param bRec A BSDF query record
386  * \param sample A uniformly distributed sample on \f$[0,1]^2\f$
387  * \param pdf Will record the probability with respect to solid angles
388  * (or the discrete probability when a delta component is sampled)
389  *
390  * \return The BSDF value (multiplied by the cosine foreshortening
391  * factor when a non-delta component is sampled). A zero spectrum
392  * means that sampling failed.
393  *
394  * \remark From Python, this function is is called using the syntax
395  * <tt>value, pdf = bsdf.sample(bRec, sample)</tt>
396  */
397  virtual Spectrum sample(BSDFSamplingRecord &bRec, Float &pdf,
398  const Point2 &sample) const = 0;
399 
400  /**
401  * \brief Evaluate the BSDF f(wi, wo) or its adjoint version f^{*}(wi, wo)
402  *
403  * This method allows to query the BSDF as a whole or pick out
404  * individual components. When querying a smooth (i.e. non-degenerate)
405  * component, it already multiplies the result by the cosine
406  * foreshortening factor with respect to the outgoing direction.
407  *
408  * \param bRec
409  * A record with detailed information on the BSDF query
410  *
411  * \param measure
412  * Specifies the measure of the component. This is necessary
413  * to handle BSDFs, whose components live on spaces with
414  * different measures. (E.g. a diffuse material with an
415  * ideally smooth dielectric coating).
416  */
417  virtual Spectrum eval(const BSDFSamplingRecord &bRec,
418  EMeasure measure = ESolidAngle) const = 0;
419 
420  /**
421  * \brief Compute the probability of sampling \c bRec.wo (given
422  * \c bRec.wi).
423  *
424  * This method provides access to the probability density that
425  * would result when supplying the same BSDF query record to the
426  * \ref sample() method. It correctly handles changes in probability
427  * when only a subset of the components is chosen for sampling
428  * (this can be done using the \ref BSDFSamplingRecord::component and
429  * \ref BSDFSamplingRecord::typeMask fields).
430  *
431  * \param bRec
432  * A record with detailed information on the BSDF query
433  *
434  * \param measure
435  * Specifies the measure of the component. This is necessary
436  * to handle BSDFs, whose components live on spaces with
437  * different measures. (E.g. a diffuse material with an
438  * ideally smooth dielectric coating).
439  */
440  virtual Float pdf(const BSDFSamplingRecord &bRec,
441  EMeasure measure = ESolidAngle) const = 0;
442 
443  /**
444  * \brief For transmissive BSDFs: return the material's
445  * relative index of refraction
446  *
447  * The default implementation returns <tt>1.0</tt>.
448  *
449  * \return interior IOR / exteriorIOR
450  */
451  virtual Float getEta() const;
452 
453  /**
454  * \brief For rough BSDFs: return the root mean square
455  * surface roughness of the given BSDF component
456  *
457  * An infinite value indicates a component that is ideally diffuse
458  */
459  virtual Float getRoughness(const Intersection &its, int index) const;
460 
461  /**
462  * \brief Sometimes, BSDF models make use of a perturbed frame for
463  * internal shading computations (e.g. bump maps). This function
464  * exposes this internal frame.
465  *
466  * By default, it returns <tt>its.shFrame</tt>
467  */
468  virtual Frame getFrame(const Intersection &its) const;
469 
470  /**
471  * \brief Sometimes, BSDF models make use of a perturbed frame for
472  * internal shading computations (e.g. bump maps). This function
473  * computes the derivative of this frame with respect to the UV
474  * parameterization of the underlying shape.
475  */
476  virtual void getFrameDerivative(const Intersection &its,
477  Frame &du, Frame &dv) const;
478 
479  // =============================================================
480  //! @{ \name ConfigurableObject interface
481  // =============================================================
482 
483  /// Configure the material (called after construction by the XML parser)
484  virtual void configure();
485 
486  /// Add a child object
487  virtual void addChild(const std::string &string, ConfigurableObject *obj);
488 
489  /// Add an unnamed child
490  inline void addChild(ConfigurableObject *child) { addChild("", child); }
491 
492  /// Serialize this object to a stream
493  virtual void serialize(Stream *stream, InstanceManager *manager) const;
494 
495  /// Set the parent object
496  virtual void setParent(ConfigurableObject *parent);
497 
498  //! @}
499  // =============================================================
500 
502 protected:
503  /// Create a new BSDF instance
504  BSDF(const Properties &props);
505 
506  /// Unserialize a BSDF instance
507  BSDF(Stream *stream, InstanceManager *manager);
508 
509  /**
510  * \brief Convenience function to ensure energy conservation
511  *
512  * This function determines the component-wise maximum of the
513  * texture \c tex and checks if it is below \c max. If yes,
514  * it returns the texture unmodified. Otherwise, it wraps
515  * the texture into a \ref ScaleTexture instance (with a
516  * scaling factor chosen so that the desired maximum \c max
517  * is abided) and prints a warning.
518  */
519  Texture *ensureEnergyConservation(Texture *tex,
520  const std::string &paramName, Float max) const;
521 
522  /**
523  * \brief Convenience function to ensure energy conservation
524  *
525  * This function determines the component-wise maximum of the
526  * sum \c tex1 + \c tex2 and checks if it is below \c max. If yes,
527  * it returns the texture unmodified. Otherwise, it wraps
528  * each the texture into a \ref ScaleTexture instance (with a
529  * scaling factor chosen so that the desired maximum \c max
530  * is abided) and prints a warning.
531  */
532  std::pair<Texture *, Texture *> ensureEnergyConservation(
533  Texture *tex1, Texture *tex2, const std::string &paramName1,
534  const std::string &paramName2, Float max) const;
535 
536  /// Virtual destructor
537  virtual ~BSDF();
538 protected:
539  std::vector<unsigned int> m_components;
540  unsigned int m_combinedType;
541  bool m_usesRayDifferentials;
542  bool m_ensureEnergyConservation;
543 };
544 
546 
547 #endif /* __MITSUBA_RENDER_BSDF_H_ */
static EMeasure getMeasure(unsigned int componentType)
Return the measure corresponding to a particular component type.
Definition: bsdf.h:313
Stores a three-dimensional orthonormal coordinate frame.
Definition: frame.h:37
Generic serializable object, which supports construction from a Properties instance.
Definition: cobject.h:40
int getComponentCount() const
Return the number of components of this BSDF.
Definition: bsdf.h:288
Base class of all textures. Computes values for an arbitrary surface point. Texture2D is a specializa...
Definition: texture.h:34
Discrete measure.
Definition: common.h:66
Abstract hardware resource.
Definition: shader.h:39
Length measure.
Definition: common.h:62
This data structured contains all information that is required to sample or query a BSDF...
Definition: bsdf.h:40
Base class of all sample generators.
Definition: sampler.h:66
ETypeCombinations
Convenient combinations of flags from EBSDFType.
Definition: bsdf.h:266
unsigned int typeMask
Bit mask containing the requested BSDF component types that should be sampled/evaluated.
Definition: bsdf.h:172
#define MTS_NAMESPACE_BEGIN
Definition: platform.h:137
virtual Spectrum getSpecularReflectance(const Intersection &its) const
Return the specular reflectance value (if any)
Definition: bsdf.h:340
EBSDFType
This list of flags is used to classify the different types of lobes that are implemented in a BSDF in...
Definition: bsdf.h:224
Vector wo
Normalized outgoing direction in local coordinates.
Definition: bsdf.h:151
const Intersection & its
Reference to the underlying surface interaction.
Definition: bsdf.h:124
virtual void serialize(Stream *stream, InstanceManager *manager) const
Serialize this object to a binary data stream.
EMeasure
A list of measures that are associated with various sampling methods in Mitsuba.
Definition: common.h:56
unsigned int sampledType
Stores the component type that was sampled by BSDF::sample()
Definition: bsdf.h:187
bool hasComponent(unsigned int type) const
Test whether this BSDF contains a certain type of component.
Definition: bsdf.h:327
bool usesRayDifferentials() const
Return whether this BSDF makes use of ray differentials.
Definition: bsdf.h:332
virtual void addChild(const std::string &name, ConfigurableObject *child)
Add a child (default implementation throws an error)
#define Log(level, fmt,...)
Write a Log message to the console (to be used within subclasses of Object)
Definition: logger.h:35
Sampler * sampler
Pointer to a Sampler instance (optional).
Definition: bsdf.h:135
Solid angle measure.
Definition: common.h:60
Abstract seekable stream class.
Definition: stream.h:58
#define MTS_DECLARE_CLASS()
This macro must be used in the initial definition in classes that derive from Object.
Definition: class.h:158
Float eta
Relative index of refraction in the sampled direction.
Definition: bsdf.h:154
int sampledComponent
Stores the component index that was sampled by BSDF::sample()
Definition: bsdf.h:192
Definition: fwd.h:99
virtual void configure()
Configure the object (called once after construction and addition of all child ConfigurableObject ins...
ETransportMode mode
Transported mode (radiance or importance)
Definition: bsdf.h:161
virtual void setParent(ConfigurableObject *parent)
Notify the ConfigurableObject instance about its parent object.
Abstract BSDF base-class.
Definition: bsdf.h:215
Definition: fwd.h:96
Error message, causes an exception to be thrown.
Definition: formatter.h:33
unsigned int getType(int component) const
Definition: bsdf.h:305
int component
Integer value specifying the requested BSDF component index that should be sampled/evaluated (for mul...
Definition: bsdf.h:181
void addChild(ConfigurableObject *child)
Add an unnamed child.
Definition: bsdf.h:490
unsigned int getType() const
Return a listing of this BSDF&#39;s component types and properties, combined using binary OR...
Definition: bsdf.h:297
Associative parameter map for constructing subclasses of ConfigurableObject.
Definition: properties.h:46
Container for all information related to a surface intersection.
Definition: shape.h:36
Coordinates the serialization and unserialization of object graphs.
Definition: serialization.h:65
#define MTS_EXPORT_RENDER
Definition: platform.h:109
Discrete spectral power distribution based on a number of wavelength bins over the 360-830 nm range...
Definition: spectrum.h:663
Radiance transport.
Definition: common.h:38
Vector wi
Normalized incident direction in local coordinates.
Definition: bsdf.h:143
#define MTS_NAMESPACE_END
Definition: platform.h:138
ETransportMode
Specifies the transport mode when sampling or evaluating a scattering function.
Definition: common.h:33