improvements to the dielectric material
parent
626794b94a
commit
54fb516737
|
@ -2,6 +2,12 @@
|
||||||
to be tested for consistency. This is done
|
to be tested for consistency. This is done
|
||||||
using the testcase 'test_chisquare' -->
|
using the testcase 'test_chisquare' -->
|
||||||
<scene>
|
<scene>
|
||||||
|
<!-- Test the dielectric model -->
|
||||||
|
<bsdf type="dielectric">
|
||||||
|
<string name="intIOR" value="water"/>
|
||||||
|
<string name="extIOR" value="air"/>
|
||||||
|
</bsdf>
|
||||||
|
|
||||||
<!-- Test the diffuse model -->
|
<!-- Test the diffuse model -->
|
||||||
<bsdf type="diffuse"/>
|
<bsdf type="diffuse"/>
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
\end{tabular}}
|
\end{tabular}}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
\setlength\fboxrule\fboxrulebackup
|
\setlength\fboxrule\fboxrulebackup
|
||||||
|
\arrayrulecolor{black}
|
||||||
}
|
}
|
||||||
|
|
||||||
\newcommand{\renderings}[1]{
|
\newcommand{\renderings}[1]{
|
||||||
|
|
|
@ -13,6 +13,8 @@ Import('env', 'plugins')
|
||||||
#plugins += env.SharedLibrary('roughdiffuse', ['roughdiffuse.cpp'])
|
#plugins += env.SharedLibrary('roughdiffuse', ['roughdiffuse.cpp'])
|
||||||
|
|
||||||
|
|
||||||
|
plugins += env.SharedLibrary('dielectric', ['dielectric.cpp'])
|
||||||
|
|
||||||
# Diffuse models
|
# Diffuse models
|
||||||
plugins += env.SharedLibrary('difftrans', ['difftrans.cpp'])
|
plugins += env.SharedLibrary('difftrans', ['difftrans.cpp'])
|
||||||
plugins += env.SharedLibrary('diffuse', ['diffuse.cpp'])
|
plugins += env.SharedLibrary('diffuse', ['diffuse.cpp'])
|
||||||
|
@ -21,7 +23,6 @@ plugins += env.SharedLibrary('diffuse', ['diffuse.cpp'])
|
||||||
plugins += env.SharedLibrary('mixture', ['mixture.cpp'])
|
plugins += env.SharedLibrary('mixture', ['mixture.cpp'])
|
||||||
|
|
||||||
#plugins += env.SharedLibrary('twosided', ['twosided.cpp'])
|
#plugins += env.SharedLibrary('twosided', ['twosided.cpp'])
|
||||||
#plugins += env.SharedLibrary('dielectric', ['dielectric.cpp'])
|
|
||||||
|
|
||||||
#plugins += env.SharedLibrary('difftrans', ['difftrans.cpp'])
|
#plugins += env.SharedLibrary('difftrans', ['difftrans.cpp'])
|
||||||
#plugins += env.SharedLibrary('mask', ['mask.cpp'])
|
#plugins += env.SharedLibrary('mask', ['mask.cpp'])
|
||||||
|
|
|
@ -18,14 +18,17 @@
|
||||||
|
|
||||||
#include <mitsuba/render/bsdf.h>
|
#include <mitsuba/render/bsdf.h>
|
||||||
#include <mitsuba/render/consttexture.h>
|
#include <mitsuba/render/consttexture.h>
|
||||||
|
#include "ior.h"
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
/*! \plugin{dielectric}{Smooth dielectric material}
|
/*! \plugin{dielectric}{Smooth dielectric material}
|
||||||
*
|
*
|
||||||
* \parameters{
|
* \parameters{
|
||||||
* \parameter{intIOR}{\Float}{Interior index of refraction \default{1.5046}}
|
* \parameter{intIOR}{\Float\Or\String}{Interior index of refraction specified
|
||||||
* \parameter{extIOR}{\Float}{Exterior index of refraction \default{1.0}}
|
* 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
|
* \parameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
|
||||||
* factor used to modulate the reflectance component\default{1.0}}
|
* factor used to modulate the reflectance component\default{1.0}}
|
||||||
* \lastparameter{specular\showbreak Transmittance}{\Spectrum\Or\Texture}{Optional
|
* \lastparameter{specular\showbreak Transmittance}{\Spectrum\Or\Texture}{Optional
|
||||||
|
@ -49,14 +52,14 @@ MTS_NAMESPACE_BEGIN
|
||||||
* In this model, the microscopic surface structure of the surface is assumed to be perfectly
|
* In this model, the microscopic surface structure of the surface is assumed to be perfectly
|
||||||
* smooth, resulting in a degenerate\footnote{Meaning that for any given incoming ray of light,
|
* 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.}
|
* 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 describes a rough
|
* BSDF described by a Dirac delta function. For a similar model that instead describes a
|
||||||
* surface microstructure, take a look at the \pluginref{roughdielectric} plugin.
|
* rough surface microstructure, take a look at the \pluginref{roughdielectric} plugin.
|
||||||
*
|
*
|
||||||
* \begin{xml}[caption=A simple air-to-water interface, label=lst:dielectric-water]
|
* \begin{xml}[caption=A simple air-to-water interface, label=lst:dielectric-water]
|
||||||
* <shape type="...">
|
* <shape type="...">
|
||||||
* <bsdf type="dielectric">
|
* <bsdf type="dielectric">
|
||||||
* <float name="intIOR" value="1.33"/>
|
* <string name="intIOR" value="water"/>
|
||||||
* <float name="extIOR" value="1.0"/>
|
* <string name="extIOR" value="air"/>
|
||||||
* </bsdf>
|
* </bsdf>
|
||||||
* <shape>
|
* <shape>
|
||||||
* \end{xml}
|
* \end{xml}
|
||||||
|
@ -68,29 +71,74 @@ MTS_NAMESPACE_BEGIN
|
||||||
* In many cases, we will want to additionally describe the \emph{medium} within a
|
* In many cases, we will want to additionally describe the \emph{medium} within a
|
||||||
* dielectric material. This requires the use of a rendering technique that is
|
* dielectric material. This requires the use of a rendering technique that is
|
||||||
* aware of media (e.g. the volumetric path tracer). An example of how one might
|
* aware of media (e.g. the volumetric path tracer). An example of how one might
|
||||||
* describe a slightly absorbing piece of glass is given below:
|
* describe a slightly absorbing piece of glass is given on the next page:
|
||||||
*
|
* \newpage
|
||||||
* \begin{xml}[caption=A glass material with absorption, label=lst:dielectric-glass]
|
* \begin{xml}[caption=A glass material with absorption (based on the
|
||||||
|
* Beer-Lambert law). This material can only be used by an integrator
|
||||||
|
* that is aware of participating media., label=lst:dielectric-glass]
|
||||||
* <shape type="...">
|
* <shape type="...">
|
||||||
* <bsdf type="dielectric">
|
* <bsdf type="dielectric">
|
||||||
* <float name="intIOR" value="1.504"/>
|
* <float name="intIOR" value="1.504"/>
|
||||||
* <float name="extIOR" value="1.0"/>
|
* <float name="extIOR" value="1.0"/>
|
||||||
* </bsdf>
|
* </bsdf>
|
||||||
|
*
|
||||||
* <medium type="homogeneous" name="interior">
|
* <medium type="homogeneous" name="interior">
|
||||||
* <rgb name="sigmaS" value="0, 0, 0"/>
|
* <rgb name="sigmaS" value="0, 0, 0"/>
|
||||||
* <rgb name="sigmaA" value="4, 4, 2"/>
|
* <rgb name="sigmaA" value="4, 4, 2"/>
|
||||||
* </medium>
|
* </medium>
|
||||||
* <shape>
|
* <shape>
|
||||||
* \end{xml}
|
* \end{xml}
|
||||||
|
* \vspace{1cm}
|
||||||
|
*
|
||||||
|
* \begin{table}[h!]
|
||||||
|
* \centering
|
||||||
|
* \begin{tabular}{>{\ttfamily}p{5cm}r@{.}lp{.8cm}>{\ttfamily}p{5cm}r@{.}l}
|
||||||
|
* \toprule
|
||||||
|
* \rmfamily Name & \multicolumn{2}{l}{Value}& &
|
||||||
|
* \rmfamily Name & \multicolumn{2}{l}{Value}\\
|
||||||
|
* \cmidrule{1-3} \cmidrule{5-7}
|
||||||
|
* vacuum & 1 & 0 & &
|
||||||
|
* silicone oil & 1 & 52045\\
|
||||||
|
* helium & 1 & 00004 & &
|
||||||
|
* bromine & 1 & 661\\
|
||||||
|
* hydrogen & 1 & 00013& &
|
||||||
|
* water ice & 1 & 31\\[-.8mm]
|
||||||
|
* \cmidrule{5-7}\\[-5.5mm]
|
||||||
|
* air & 1 & 00028& &
|
||||||
|
* fused quartz & 1 & 458\\
|
||||||
|
* carbon dioxide & 1 & 00045& &
|
||||||
|
* pyrex & 1 & 470\\[-.8mm]
|
||||||
|
* \cmidrule{1-3}\\[-5.5mm]
|
||||||
|
* water & 1 & 3330& &
|
||||||
|
* acrylic glass & 1 & 490\\
|
||||||
|
* acetone & 1 & 36 & &
|
||||||
|
* bk7 & 1 & 5046\\
|
||||||
|
* ethanol & 1 & 361& &
|
||||||
|
* sodium chloride & 1 & 544\\
|
||||||
|
* carbon tetrachloride & 1 & 461& &
|
||||||
|
* amber & 1 & 55\\
|
||||||
|
* glycerol & 1 & 4729& &
|
||||||
|
* pet & 1 & 575\\
|
||||||
|
* benzene & 1 & 501& &
|
||||||
|
* diamond & 2 & 419\\
|
||||||
|
* \bottomrule
|
||||||
|
* \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.
|
||||||
|
* }
|
||||||
|
* \end{table}
|
||||||
*/
|
*/
|
||||||
class SmoothDielectric : public BSDF {
|
class SmoothDielectric : public BSDF {
|
||||||
public:
|
public:
|
||||||
SmoothDielectric(const Properties &props)
|
SmoothDielectric(const Properties &props) : BSDF(props) {
|
||||||
: BSDF(props) {
|
|
||||||
/* Specifies the internal index of refraction at the interface */
|
/* Specifies the internal index of refraction at the interface */
|
||||||
m_intIOR = props.getFloat("intIOR", 1.5046f);
|
m_intIOR = lookupIOR(props, "intIOR", "bk7");
|
||||||
|
|
||||||
/* Specifies the external index of refraction at the interface */
|
/* Specifies the external index of refraction at the interface */
|
||||||
m_extIOR = props.getFloat("extIOR", 1);
|
m_extIOR = lookupIOR(props, "extIOR", "air");
|
||||||
|
|
||||||
m_specularReflectance = new ConstantSpectrumTexture(
|
m_specularReflectance = new ConstantSpectrumTexture(
|
||||||
props.getSpectrum("specularReflectance", Spectrum(1.0f)));
|
props.getSpectrum("specularReflectance", Spectrum(1.0f)));
|
||||||
|
@ -199,7 +247,7 @@ public:
|
||||||
} else {
|
} else {
|
||||||
bRec.sampledComponent = 1;
|
bRec.sampledComponent = 1;
|
||||||
bRec.sampledType = EDeltaTransmission;
|
bRec.sampledType = EDeltaTransmission;
|
||||||
;
|
|
||||||
/* Given cos(N, transmittedRay), compute the
|
/* Given cos(N, transmittedRay), compute the
|
||||||
transmitted direction */
|
transmitted direction */
|
||||||
bRec.wo = refract(bRec.wi, eta, cosThetaT);
|
bRec.wo = refract(bRec.wi, eta, cosThetaT);
|
||||||
|
@ -230,15 +278,15 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spectrum eval(const BSDFQueryRecord &bRec) const {
|
Spectrum eval(const BSDFQueryRecord &bRec, EMeasure measure) const {
|
||||||
bool sampleReflection = (bRec.typeMask & EDeltaReflection)
|
bool sampleReflection = (bRec.typeMask & EDeltaReflection)
|
||||||
&& (bRec.component == -1 || bRec.component == 0);
|
&& (bRec.component == -1 || bRec.component == 0);
|
||||||
bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
|
bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
|
||||||
&& (bRec.component == -1 || bRec.component == 1);
|
&& (bRec.component == -1 || bRec.component == 1);
|
||||||
bool reflection = BSDF::cosTheta(bRec.wo) * BSDF::cosTheta(bRec.wi) > 0;
|
bool reflection = Frame::cosTheta(bRec.wo) * Frame::cosTheta(bRec.wi) > 0;
|
||||||
|
|
||||||
if ((reflection && !sampleReflection) ||
|
if ((reflection && !sampleReflection) ||
|
||||||
(!reflection && !sampleTransmission))
|
(!reflection && !sampleTransmission) || measure != EDiscrete)
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
Float fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
|
Float fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
|
||||||
|
@ -263,18 +311,18 @@ public:
|
||||||
&& (bRec.component == -1 || bRec.component == 0);
|
&& (bRec.component == -1 || bRec.component == 0);
|
||||||
bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
|
bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
|
||||||
&& (bRec.component == -1 || bRec.component == 1);
|
&& (bRec.component == -1 || bRec.component == 1);
|
||||||
|
bool reflection = Frame::cosTheta(bRec.wo)
|
||||||
if (measure != EDiscrete || (!sampleReflection && !sampleTransmission))
|
|
||||||
return 0.0f;
|
|
||||||
|
|
||||||
bool reflection = Frame::costheta(bRec.wo)
|
|
||||||
* Frame::cosTheta(bRec.wi) > 0;
|
* Frame::cosTheta(bRec.wi) > 0;
|
||||||
|
|
||||||
|
if ((reflection && !sampleReflection) ||
|
||||||
|
(!reflection && !sampleTransmission) || measure != EDiscrete)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
if (sampleTransmission && sampleReflection) {
|
if (sampleTransmission && sampleReflection) {
|
||||||
Float Fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
|
Float Fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
|
||||||
return reflection ? Fr : (1 - Fr);
|
return reflection ? Fr : (1 - Fr);
|
||||||
} else {
|
} else {
|
||||||
return sampleReflection == reflection ? 1.0f : 0.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
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(__IOR_DATA_H)
|
||||||
|
#define __IOR_DATA_H
|
||||||
|
|
||||||
|
#include <mitsuba/mitsuba.h>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
struct IOREntry {
|
||||||
|
const char *name;
|
||||||
|
Float value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Many values are taken from Hecht, Optics,
|
||||||
|
* Fourth Edition.
|
||||||
|
*
|
||||||
|
* The IOR values are from measurements between
|
||||||
|
* 0 and 20 degrees celsius at ~589 nm.
|
||||||
|
*/
|
||||||
|
static IOREntry iorData[] = {
|
||||||
|
{ "vacuum", 1.0f },
|
||||||
|
{ "helium", 1.000036f },
|
||||||
|
{ "hydrogen", 1.000132f },
|
||||||
|
{ "air", 1.000277f },
|
||||||
|
{ "carbon dioxide", 1.00045f },
|
||||||
|
//////////////////////////////////////
|
||||||
|
{ "water", 1.3330f },
|
||||||
|
{ "acetone", 1.36f },
|
||||||
|
{ "ethanol", 1.361f },
|
||||||
|
{ "carbon tetrachloride", 1.461f },
|
||||||
|
{ "glycerol", 1.4729f },
|
||||||
|
{ "benzene", 1.501f },
|
||||||
|
{ "silicone oil", 1.52045f },
|
||||||
|
{ "bromine", 1.661f },
|
||||||
|
//////////////////////////////////////
|
||||||
|
{ "water ice", 1.31f },
|
||||||
|
{ "fused quartz", 1.458f },
|
||||||
|
{ "pyrex", 1.470f },
|
||||||
|
{ "acrylic glass", 1.490f },
|
||||||
|
{ "bk7", 1.5046f },
|
||||||
|
{ "sodium chloride", 1.544f },
|
||||||
|
{ "amber", 1.55f },
|
||||||
|
{ "pet", 1.5750f },
|
||||||
|
{ "diamond", 2.419f },
|
||||||
|
|
||||||
|
{ NULL, 0.0f }
|
||||||
|
};
|
||||||
|
|
||||||
|
static Float lookupIOR(const std::string &name) {
|
||||||
|
std::string lowerCase = boost::to_lower_copy(name);
|
||||||
|
IOREntry *ior = iorData;
|
||||||
|
|
||||||
|
while (ior->name) {
|
||||||
|
if (lowerCase == ior->name)
|
||||||
|
return ior->value;
|
||||||
|
++ior;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "Unable to find an IOR value for \"" << lowerCase
|
||||||
|
<< "\"! Valid choices are:";
|
||||||
|
|
||||||
|
/* Unable to find the IOR value by name -- print an error
|
||||||
|
message that lists all possible options */
|
||||||
|
for (ior = iorData; ior->name != NULL; ++ior) {
|
||||||
|
oss << ior->name;
|
||||||
|
if ((ior+1)->name)
|
||||||
|
oss << ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
SLog(EError, "%s", oss.str().c_str());
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Float lookupIOR(const Properties &props, const std::string ¶mName, const std::string &defaultValue) {
|
||||||
|
if (props.hasProperty(paramName) && props.getType(paramName) == Properties::EFloat)
|
||||||
|
return props.getFloat(paramName);
|
||||||
|
else
|
||||||
|
return lookupIOR(props.getString(paramName, defaultValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
MTS_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif /* __IOR_DATA_H */
|
Loading…
Reference in New Issue