mitsuba/include/mitsuba/render/phase.h

201 lines
6.4 KiB
C++

/*
This file is part of Mitsuba, a physically based rendering system.
Copyright (c) 2007-2011 by Wenzel Jakob and others.
Mitsuba is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License Version 3
as published by the Free Software Foundation.
Mitsuba is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__PHASE_H)
#define __PHASE_H
#include <mitsuba/core/netobject.h>
#include <mitsuba/render/common.h>
MTS_NAMESPACE_BEGIN
/**
* \brief Data structure, which contains information
* required to sample or query a phase function.
*
* \ingroup librender
*/
struct MTS_EXPORT_RENDER PhaseFunctionQueryRecord {
/**
* \brief Reference to a Medium sampling record created
* by \ref Medium::sampleDistance()
*/
const MediumSamplingRecord &mRec;
/**
* \brief Normalized incident direction vector, which points away
* from the scattering event.
*
* In Mitsuba, the direction convention for phase functions is the
* same as for BSDFs, as opposed to much of the literature, where
* \a wi points inwards.
*/
Vector wi;
/// Normalized outgoing direction vector
Vector wo;
/* Transported quantity (radiance or importance) -- required for
rendering with non-reciprocal phase functions */
ETransportMode quantity;
/**
* \brief Given a medium interaction and an incident direction,
* construct a query record which can be used to sample an outgoing
* direction.
*
* \param mRec
* An reference to the underlying medium sampling record
* \param wi
* An incident direction in world coordinates. This should
* be a normalized direction vector that points \a away from
* the scattering event.
* \param quantity
* The transported quantity (\ref ERadiance or \ref EImportance)
*/
inline PhaseFunctionQueryRecord(const MediumSamplingRecord &mRec,
const Vector &wi, ETransportMode quantity = ERadiance)
: mRec(mRec), wi(wi), quantity(quantity) { }
/*
* \brief Given a medium interaction an an incident/exitant direction
* pair (wi, wo), create a query record to evaluate the phase function
* or its sampling density.
*
* \param mRec
* An reference to the underlying medium sampling record
* \param wi
* An incident direction in world coordinates. This should
* be a normalized direction vector that points \a away from
* the scattering event.
* \param wo
* An outgoing direction in world coordinates. This should
* be a normalized direction vector that points \a away from
* the scattering event.
* \param quantity
* The transported quantity (\ref ERadiance or \ref EImportance)
*/
inline PhaseFunctionQueryRecord(const MediumSamplingRecord &mRec,
const Vector &wi, const Vector &wo, ETransportMode quantity = ERadiance)
: mRec(mRec), wi(wi), wo(wo), quantity(quantity) { }
std::string toString() const;
};
/** \brief Abstract phase function.
* \ingroup librender
*/
class MTS_EXPORT_RENDER PhaseFunction : public ConfigurableObject {
public:
/**
* \brief Evaluate the phase function for an outward-pointing
* pair of directions (wi, wo)
*/
virtual Float eval(const PhaseFunctionQueryRecord &pRec) const = 0;
/**
* \brief Sample the phase function and return the importance weight (i.e. the
* value of the phase function divided by the probability density of the sample).
*
* When the probability density is not explicitly required, this function
* should be preferred, since it is potentially faster by making use of
* cancellations during the division.
*
* \param pRec A phase function query record
* \param sampler A sample generator
*
* \return The phase function value divided by the probability
* density of the sample
*/
virtual Float sample(PhaseFunctionQueryRecord &pRec,
Sampler *sampler) const = 0;
/**
* \brief Sample the phase function and return the probability density \a and the
* importance weight of the sample (i.e. the value of the phase function divided
* by the probability density)
*
* \param pRec A phase function query record
* \param sampler A sample generator
* \param pdf Will record the probability with respect to solid angles
*
* \return The phase function value divided by the probability
* density of the sample
*/
virtual Float sample(PhaseFunctionQueryRecord &pRec,
Float &pdf, Sampler *sampler) const = 0;
/**
* \brief Calculate the probability of sampling wo (given wi).
*
* Assuming that the phase function can be sampled exactly,
* the default implementation just evaluates \ref eval()
*/
virtual Float pdf(const PhaseFunctionQueryRecord &pRec) const;
/**
* \brief Does this phase function require directionally varying scattering
* and extinction coefficients?
*
* This is used to implement rendering of media that have an anisotropic
* structure (cf. "A radiative transfer framework for rendering materials with
* anisotropic structure" by Wenzel Jakob, Adam Arbree, Jonathan T. Moon,
* Kavita Bala, and Steve Marschner, SIGGRAPH 2010)
*/
virtual bool needsDirectionallyVaryingCoefficients() const;
/**
* \brief For anisotropic media: evaluate the directionally varying component
* of the scattering and absorption coefficients.
*
* \param cosTheta
* Angle between the axis of rotational symmetry and the
* direction of propagation
*/
virtual Float sigmaDir(Float cosTheta) const;
/**
* \brief Returns the maximum value take on on by \ref sigmaDirMax().
* This is useful when implementing Woodcock tracking.
*/
virtual Float sigmaDirMax() const;
/// Return a string representation
virtual std::string toString() const = 0;
MTS_DECLARE_CLASS()
protected:
/// Create a new phase function instance
inline PhaseFunction(const Properties &props) :
ConfigurableObject(props) { }
/// Unserialize a phase function
inline PhaseFunction(Stream *stream, InstanceManager *manager) :
ConfigurableObject(stream, manager) { }
/// Virtual destructor
virtual ~PhaseFunction() { }
private:
bool m_dvSigmaT;
};
MTS_NAMESPACE_END
#endif /* __PHASE_H */