improvements to the dielectric material

metadata
Wenzel Jakob 2011-07-04 23:39:44 +02:00
parent 626794b94a
commit 54fb516737
5 changed files with 183 additions and 24 deletions

View File

@ -2,6 +2,12 @@
to be tested for consistency. This is done
using the testcase 'test_chisquare' -->
<scene>
<!-- Test the dielectric model -->
<bsdf type="dielectric">
<string name="intIOR" value="water"/>
<string name="extIOR" value="air"/>
</bsdf>
<!-- Test the diffuse model -->
<bsdf type="diffuse"/>

View File

@ -40,6 +40,7 @@
\end{tabular}}
\end{figure}
\setlength\fboxrule\fboxrulebackup
\arrayrulecolor{black}
}
\newcommand{\renderings}[1]{

View File

@ -13,6 +13,8 @@ Import('env', 'plugins')
#plugins += env.SharedLibrary('roughdiffuse', ['roughdiffuse.cpp'])
plugins += env.SharedLibrary('dielectric', ['dielectric.cpp'])
# Diffuse models
plugins += env.SharedLibrary('difftrans', ['difftrans.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('twosided', ['twosided.cpp'])
#plugins += env.SharedLibrary('dielectric', ['dielectric.cpp'])
#plugins += env.SharedLibrary('difftrans', ['difftrans.cpp'])
#plugins += env.SharedLibrary('mask', ['mask.cpp'])

View File

@ -18,14 +18,17 @@
#include <mitsuba/render/bsdf.h>
#include <mitsuba/render/consttexture.h>
#include "ior.h"
MTS_NAMESPACE_BEGIN
/*! \plugin{dielectric}{Smooth dielectric material}
*
* \parameters{
* \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
@ -49,14 +52,14 @@ MTS_NAMESPACE_BEGIN
* 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,
* 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
* surface microstructure, take a look at the \pluginref{roughdielectric} plugin.
* BSDF described by a Dirac delta function. 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]
* <shape type="...">
* <bsdf type="dielectric">
* <float name="intIOR" value="1.33"/>
* <float name="extIOR" value="1.0"/>
* <string name="intIOR" value="water"/>
* <string name="extIOR" value="air"/>
* </bsdf>
* <shape>
* \end{xml}
@ -68,29 +71,74 @@ MTS_NAMESPACE_BEGIN
* 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
* 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:
*
* \begin{xml}[caption=A glass material with absorption, label=lst:dielectric-glass]
* describe a slightly absorbing piece of glass is given on the next page:
* \newpage
* \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="...">
* <bsdf type="dielectric">
* <float name="intIOR" value="1.504"/>
* <float name="extIOR" value="1.0"/>
* </bsdf>
*
* <medium type="homogeneous" name="interior">
* <rgb name="sigmaS" value="0, 0, 0"/>
* <rgb name="sigmaA" value="4, 4, 2"/>
* </medium>
* <shape>
* \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 {
public:
SmoothDielectric(const Properties &props)
: BSDF(props) {
SmoothDielectric(const Properties &props) : BSDF(props) {
/* 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 */
m_extIOR = props.getFloat("extIOR", 1);
m_extIOR = lookupIOR(props, "extIOR", "air");
m_specularReflectance = new ConstantSpectrumTexture(
props.getSpectrum("specularReflectance", Spectrum(1.0f)));
@ -199,7 +247,7 @@ public:
} else {
bRec.sampledComponent = 1;
bRec.sampledType = EDeltaTransmission;
;
/* Given cos(N, transmittedRay), compute the
transmitted direction */
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)
&& (bRec.component == -1 || bRec.component == 0);
bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
&& (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) ||
(!reflection && !sampleTransmission))
(!reflection && !sampleTransmission) || measure != EDiscrete)
return Spectrum(0.0f);
Float fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
@ -263,18 +311,18 @@ public:
&& (bRec.component == -1 || bRec.component == 0);
bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
&& (bRec.component == -1 || bRec.component == 1);
if (measure != EDiscrete || (!sampleReflection && !sampleTransmission))
return 0.0f;
bool reflection = Frame::costheta(bRec.wo)
bool reflection = Frame::cosTheta(bRec.wo)
* Frame::cosTheta(bRec.wi) > 0;
if ((reflection && !sampleReflection) ||
(!reflection && !sampleTransmission) || measure != EDiscrete)
return 0.0f;
if (sampleTransmission && sampleReflection) {
Float Fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
return reflection ? Fr : (1 - Fr);
} else {
return sampleReflection == reflection ? 1.0f : 0.0f;
return 1.0f;
}
}

103
src/bsdfs/ior.h Normal file
View File

@ -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 &paramName, 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 */