metadata
Wenzel Jakob 2011-07-07 18:50:43 +02:00
parent 736a8e6866
commit dacb6f96b6
3 changed files with 140 additions and 67 deletions

View File

@ -26,17 +26,20 @@ MTS_NAMESPACE_BEGIN
* \parameters{
* \parameter{preset}{\String}{Name of a material preset, see
* \tblref{conductor-iors}.\!\default{\texttt{Cu} / copper}}
* \parameter{eta}{\Spectrum}{Real part of the material's index of refraction
* \default{based on the value of \texttt{preset}}}
* \parameter{eta}{\Spectrum}{Real part of the material's index
* of refraction \default{based on the value of \texttt{preset}}}
* \parameter{k}{\Spectrum}{Imaginary part of the material's index of
* refraction, also known as absorption coefficient.
* \default{based on the value of \texttt{preset}}}
* \lastparameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
* factor used to modulate the reflectance component\default{1.0}}
* \lastparameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{
* Optional factor used to modulate the reflectance component
* \default{1.0}}
* }
* \renderings{
* \rendering{Measured copper material (the default)}{bsdf_conductor_copper.jpg}
* \rendering{Measured gold material (\lstref{conductor-gold})}{bsdf_conductor_gold.jpg}
* \rendering{Measured copper material (the default)}
* {bsdf_conductor_copper.jpg}
* \rendering{Measured gold material (\lstref{conductor-gold})}
* {bsdf_conductor_gold.jpg}
* }
* This plugin implements a perfectly smooth interface to a conducting material,
@ -50,18 +53,20 @@ MTS_NAMESPACE_BEGIN
*
* To faciliate the tedious task of specifying spectrally-varying index of
* refraction information, Mitsuba ships with a set of measured data for a
* several materials, where visible-spectrum information was publicly available\footnote{
* These index of refraction values are identical to the data distributed with PBRT.
* They are originally from the Luxpop database (\url{www.luxpop.com}) and
* are based on data by Palik et al. \cite{Palik1998Handbook} and measurements
* of atomic scattering factors made by the Center For X-Ray Optics (CXRO)
* at Berkeley and the Lawrence Livermore National Laboratory (LLNL).
* several materials, where visible-spectrum information was publicly
* available\footnote{
* These index of refraction values are identical to the data distributed
* with PBRT. They are originally from the Luxpop database
* (\url{www.luxpop.com}) and are based on data by Palik et al.
* \cite{Palik1998Handbook} and measurements of atomic scattering factors
* made by the Center For X-Ray Optics (CXRO) at Berkeley and the
* Lawrence Livermore National Laboratory (LLNL).
* }.
*
* Note that \tblref{conductor-iors} also includes several popular optical coatings, which are
* not actually conductors. These materials can also be used with this plugin,
* though note that the plugin will ignore any refraction component that the actual
* material might have had.
* Note that \tblref{conductor-iors} also includes several popular optical
* coatings, which are not actually conductors. These materials can also
* be used with this plugin, though note that the plugin will ignore any
* refraction component that the actual material might have had.
* The table also contains a few birefingent materials, which are split into
* separate measurements correponding to their two indices of
* refraction (named ``ordinary'' and ``extraordinary ray'').
@ -70,7 +75,8 @@ MTS_NAMESPACE_BEGIN
* renderings to get the most accurate results. While it also works in RGB mode,
* the computations will be much more approximate in this case.
*
* \begin{xml}[caption=Material configuration for a smooth conductor with measured gold data, label=lst:conductor-gold]
* \begin{xml}[caption=Material configuration for a smooth conductor with
* measured gold data, label=lst:conductor-gold]
* <shape type="...">
* <bsdf type="conductor">
* <string name="preset" value="Au"/>
@ -79,7 +85,8 @@ MTS_NAMESPACE_BEGIN
* \end{xml}
* \vspace{5mm}
* It is also possible to load spectrally varying index of refraction data from
* two external files (see \secref{format-spectra} for details on the file format):
* two external files (see \secref{format-spectra} for details on the file
* format):
* \begin{xml}[caption=Rendering a smooth conductor with custom data]
* <shape type="...">
* <bsdf type="conductor">
@ -121,12 +128,13 @@ MTS_NAMESPACE_BEGIN
* \end{tabular}
* \caption{
* \label{tbl:conductor-iors}
* This table lists all supported material names that can be passed into the
* \pluginref{conductor} plugin. Note that some of them are not actually
* conductors---this is not a problem, they can be used regardless (though only
* the reflection component and no transmission will be simulated).
* In most cases, there are multiple entries for each material, which
* represent different measurements.
* This table lists all supported materials that can be passed into the
* \pluginref{conductor} and \pluginref{roughconductor} plugins. Note that
* some of them are not actually conductors---this is not a problem,
* they can be used regardless (though only the reflection component and
* no transmission will be simulated). In most cases, there are
* multiple entries for each material, which represent measurements by
* different authors.
* }
* \end{table}
*/
@ -196,9 +204,12 @@ public:
bool sampleReflection = (bRec.typeMask & EDeltaReflection)
&& (bRec.component == -1 || bRec.component == 0);
/* Verify that the provided direction pair matches an ideal
specular reflection; tolerate some roundoff errors */
if (!sampleReflection || measure != EDiscrete ||
Frame::cosTheta(bRec.wi) <= 0 ||
Frame::cosTheta(bRec.wo) <= 0)
Frame::cosTheta(bRec.wo) <= 0 ||
std::abs(1 - dot(reflect(bRec.wi), bRec.wo)) > Epsilon)
return Spectrum(0.0f);
return m_specularReflectance->getValue(bRec.its) *
@ -208,10 +219,15 @@ public:
Float pdf(const BSDFQueryRecord &bRec, EMeasure measure) const {
bool sampleReflection = (bRec.typeMask & EDeltaReflection)
&& (bRec.component == -1 || bRec.component == 0);
if (!sampleReflection || measure != EDiscrete ||
/* Verify that the provided direction pair matches an ideal
specular reflection; tolerate some roundoff errors */
if (!sampleReflection || measure != EDiscrete ||
Frame::cosTheta(bRec.wi) <= 0 ||
Frame::cosTheta(bRec.wo) <= 0)
Frame::cosTheta(bRec.wo) <= 0 ||
std::abs(1 - dot(reflect(bRec.wi), bRec.wo)) > Epsilon)
return 0.0f;
return 1.0f;
}

View File

@ -45,14 +45,14 @@ MTS_NAMESPACE_BEGIN
*
* This plugin models an interface between two dielectric materials having mismatched
* indices of refraction (for instance, water and air). Exterior and interior IOR values
* can each be independently specified, where ``exterior'' refers to the side that contains
* can be independently specified, where ``exterior'' refers to the side that contains
* the surface normal. When no parameters are given, the plugin activates the defaults, which
* describe a borosilicate glass BK7/air interface.
*
* In this model, the microscopic surface structure of the surface is assumed to be perfectly
* In this model, the microscopic structure of the surface is assumed to be perfectly
* smooth, resulting in a degenerate\footnote{Meaning that for any given incoming ray of light,
* the model always scatters into a discrete set of directions, as opposed to a continuum.}
* BSDF described by a Dirac delta function. For a similar model that instead describes a
* BSDF described by a Dirac delta distribution. For a similar model that instead describes a
* rough surface microstructure, take a look at the \pluginref{roughdielectric} plugin.
*
* \begin{xml}[caption=A simple air-to-water interface, label=lst:dielectric-water]
@ -125,9 +125,13 @@ MTS_NAMESPACE_BEGIN
* \end{tabular}
* \caption{
* \label{tbl:dielectric-iors}
* This table lists all supported material names that can be passed
* into the \pluginref{dielectric} plugin, along with the associated
* index of refraction at standard conditions.
* This table lists all supported material names along with
* along with the associated index of refraction at
* standard conditions. These can be used with the plugins
* \pluginref{dielectric},\
* \pluginref{roughdielectric},\
* \pluginref{plastic}, and
* \pluginref{roughplastic}.
* }
* \end{table}
*/
@ -200,26 +204,66 @@ public:
return Vector(-wi.x, -wi.y, wi.z);
}
/// Refraction in local coordinates
/// Refraction in local coordinates (reuses computed information)
inline Vector refract(const Vector &wi, Float eta, Float cosThetaT) const {
return Vector(-eta*wi.x, -eta*wi.y, cosThetaT);
}
/// Refraction in local coordinates (full version)
inline Vector refract(const Vector &wi) const {
Float cosThetaI = Frame::cosTheta(wi),
etaI = m_extIOR,
etaT = m_intIOR;
bool entering = cosThetaI > 0.0f;
/* Determine the respective indices of refraction */
if (!entering)
std::swap(etaI, etaT);
/* Using Snell's law, calculate the squared sine of the
angle between the normal and the transmitted ray */
Float eta = etaI / etaT,
sinThetaTSqr = eta*eta * Frame::sinTheta2(wi);
Float cosThetaT = 0;
if (sinThetaTSqr >= 1.0f) {
/* Total internal reflection */
return Vector(0.0f);
} else {
cosThetaT = std::sqrt(1.0f - sinThetaTSqr);
if (entering)
cosThetaT = -cosThetaT;
}
return Vector(-eta*wi.x, -eta*wi.y, cosThetaT);
}
Spectrum eval(const BSDFQueryRecord &bRec, EMeasure measure) const {
bool sampleReflection = (bRec.typeMask & EDeltaReflection)
&& (bRec.component == -1 || bRec.component == 0);
bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
&& (bRec.component == -1 || bRec.component == 1);
bool reflection = Frame::cosTheta(bRec.wo) * Frame::cosTheta(bRec.wi) > 0;
if ((reflection && !sampleReflection) ||
(!reflection && !sampleTransmission) || measure != EDiscrete)
/* Check if the provided direction pair matches an ideal
specular reflection; tolerate some roundoff errors */
bool reflection = std::abs(1 - dot(reflect(bRec.wi), bRec.wo)) < Epsilon;
if (measure != EDiscrete || (reflection && !sampleReflection))
return Spectrum(0.0f);
Float fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
if (!reflection) {
/* Check if the provided direction pair matches an ideal
specular refraction; tolerate some roundoff errors */
bool refraction = std::abs(1 - dot(refract(bRec.wi), bRec.wo)) < Epsilon;
if (!refraction || !sampleTransmission)
return Spectrum(0.0f);
}
Float Fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
if (reflection) {
return m_specularReflectance->getValue(bRec.its) * fr;
return m_specularReflectance->getValue(bRec.its) * Fr;
} else {
Float etaI = m_extIOR, etaT = m_intIOR;
bool entering = Frame::cosTheta(bRec.wi) > 0.0f;
@ -229,7 +273,7 @@ public:
Float factor = (bRec.quantity == ERadiance)
? (etaI*etaI) / (etaT*etaT) : 1.0f;
return m_specularTransmittance->getValue(bRec.its) * factor * (1 - fr);
return m_specularTransmittance->getValue(bRec.its) * factor * (1 - Fr);
}
}
@ -238,13 +282,21 @@ public:
&& (bRec.component == -1 || bRec.component == 0);
bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
&& (bRec.component == -1 || bRec.component == 1);
bool reflection = Frame::cosTheta(bRec.wo)
* Frame::cosTheta(bRec.wi) > 0;
if ((reflection && !sampleReflection) ||
(!reflection && !sampleTransmission) || measure != EDiscrete)
/* Check if the provided direction pair matches an ideal
specular reflection; tolerate some roundoff errors */
bool reflection = std::abs(1 - dot(reflect(bRec.wi), bRec.wo)) < Epsilon;
if (measure != EDiscrete || (reflection && !sampleReflection))
return 0.0f;
if (!reflection) {
/* Check if the provided direction pair matches an ideal
specular refraction; tolerate some roundoff errors */
bool refraction = std::abs(1 - dot(refract(bRec.wi), bRec.wo)) < Epsilon;
if (!refraction || !sampleTransmission)
return 0.0f;
}
if (sampleTransmission && sampleReflection) {
Float Fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
return reflection ? Fr : (1 - Fr);

View File

@ -43,10 +43,9 @@ MTS_NAMESPACE_BEGIN
* behavior than the separately available \pluginref{phong} plugin.
* \item \code{ggx}: New distribution proposed by
* Walter et al. meant to better handle the long
* tails observed in transmission measurements through
* ground glass. Renderings with this distribution may
* converge slowly.
* \item \code{as}: Anisotropic microfacet distribution proposed by
* tails observed in measurements of ground surfaces.
* Renderings with this distribution may converge slowly.
* \item \code{as}: Anisotropic Phong-style microfacet distribution proposed by
* Ashikhmin and Shirley \cite{Ashikhmin2005Anisotropic}.\vspace{-3mm}
* \end{enumerate}
* }
@ -58,12 +57,14 @@ MTS_NAMESPACE_BEGIN
* \default{0.1}.
* }
* \parameter{alphaU, alphaV}{\Float\Or\Texture}{
* Specifies the anisotropic rougness values along the tangent and bitangent directions. This
* parameter is only valid when \texttt{distribution=as}.
* Specifies the anisotropic rougness values along the tangent and bitangent directions. These
* parameter are only valid when \texttt{distribution=as}.
* \default{0.1}.
* }
* \parameter{intIOR}{\Float}{Interior index of refraction \default{1.5046}}
* \parameter{extIOR}{\Float}{Exterior index of refraction \default{1.0}}
* \parameter{intIOR}{\Float\Or\String}{Interior index of refraction specified
* numerically or using a known material name. \default{\texttt{bk7} / 1.5046}}
* \parameter{extIOR}{\Float\Or\String}{Exterior index of refraction specified
* numerically or using a known material name. \default{\texttt{air} / 1.000277}}
* \parameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
* factor used to modulate the reflectance component\default{1.0}}
* \lastparameter{specular\showbreak Transmittance}{\Spectrum\Or\Texture}{Optional
@ -93,39 +94,43 @@ MTS_NAMESPACE_BEGIN
* plugin is based on the paper ``Microfacet Models for Refraction through
* Rough Surfaces'' by Walter et al. \cite{Walter07Microfacet}. It supports
* several types of microfacet distributions and has a texturable roughness
* parameter. Exterior and interior IOR values can each be independently
* parameter. Exterior and interior IOR values can be independently
* specified, where ``exterior'' refers to the side that contains the surface
* normal. When no parameters are given, the plugin activates the default
* settings, which describe a borosilicate glass BK7/air interface with a
* light amount of roughness modeled using a Beckmann distribution.
* normal. Similar to the \pluginref{dielectric} plugin, IOR values can either
* be specified numerically, or based on a list of known materials (see
* \tblref{dielectric-iors} for an overview). When no parameters are given,
* the plugin activates the default settings, which describe a borosilicate
* glass BK7/air interface with a light amount of roughness modeled using a
* Beckmann distribution.
*
* When using the Ashikmin-Shirley or Phong models, a conversion method is
* used to turn the specified $\alpha$ roughness value into the exponents
* of these distributions. This is done so that the different distributions
* all produce a similar appearance for the same value of $\alpha$.
* of these distributions. This is done in a way, such that the different
* distributions all produce a similar appearance for the same value of $\alpha$.
*
* When using this plugin, it is crucial that the scene contains
* meaningful and mutally compatible index of refraction changes---see
* \figref{glass-explanation} for an example. Also, please note that
* the importance sampling implementation of this model is close, but
* not perfect a perfect match to the underlying scattering distribution,
* particularly for high roughness values and when the \texttt{GGX}
* model is used. Hence, such renderings may converge slowly.\vspace{1cm}
* not always a perfect a perfect match to the underlying scattering distribution,
* particularly for high roughness values and when the \texttt{ggx}
* microfacet distribution is used. Hence, such renderings may
* converge slowly.\vspace{1cm}
*
* \begin{xml}[caption=Material definition for ground glass, label=lst:roughdielectric-roughglass]
* \begin{xml}[caption=A material definition for ground glass, label=lst:roughdielectric-roughglass]
* <bsdf type="roughdielectric">
* <string name="distribution" value="ggx"/>
* <float name="alpha" value="0.304"/>
* <float name="intIOR" value="1.5046"/>
* <float name="extIOR" value="1.0"/>
* <string name="intIOR" value="bk7"/>
* <string name="extIOR" value="air"/>
* </bsdf>
* \end{xml}
*
* \begin{xml}[caption=A texture can be attached to the roughness parameter, label=lst:roughdielectric-textured]
* <bsdf type="roughdielectric">
* <string name="distribution" value="beckmann"/>
* <string name="intIOR" value="bk7"/>
* <string name="extIOR" value="air"/>
* <float name="intIOR" value="1.5046"/>
* <float name="extIOR" value="1.0"/>
*
* <texture name="alpha" type="bitmap">
* <string name="filename" value="roughness.exr"/>