documentation updates, fixed for many typos, fixed the bump map model
parent
b5a6b7cbd8
commit
17eb2166f0
|
@ -20,6 +20,8 @@
|
|||
\newcommand{\Vector}{\texttt{vector}}
|
||||
\newcommand{\Point}{\texttt{point}}
|
||||
\newcommand{\Texture}{\texttt{texture}}
|
||||
\newcommand{\BSDF}{\texttt{bsdf}}
|
||||
\newcommand{\Unnamed}{\emph{(Nested plugin)}}
|
||||
\newcommand{\Or}{~~\small or \small}
|
||||
\newcolumntype{P}[1]{>{\RaggedRight\hspace{0pt}}p{#1}}
|
||||
\newcommand{\MtsVer}{\color{lstattrib}\texttt{"\MitsubaVersion"}}
|
||||
|
@ -37,7 +39,7 @@
|
|||
%\toprule
|
||||
\\[-2.2ex]
|
||||
\textbf{Parameter}&\textbf{Type}&\textbf{Description}\\
|
||||
#1
|
||||
#1\\[-4mm]
|
||||
\end{tabular}}
|
||||
\end{figure}
|
||||
\setlength\fboxrule\fboxrulebackup
|
||||
|
|
12
doc/main.bib
12
doc/main.bib
|
@ -132,3 +132,15 @@
|
|||
address = {Ithaca, NY, USA},
|
||||
note = {\url{http://ecommons.library.cornell.edu/handle/1813/8331}}
|
||||
}
|
||||
|
||||
@inproceedings{Blinn1978Simulation,
|
||||
author = {Blinn, James F.},
|
||||
title = {Simulation of wrinkled surfaces},
|
||||
booktitle = {Proceedings of the 5th annual conference on Computer graphics and interactive techniques},
|
||||
series = {SIGGRAPH '78},
|
||||
year = {1978},
|
||||
pages = {286--292},
|
||||
publisher = {ACM},
|
||||
address = {New York, NY, USA},
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,8 @@ public:
|
|||
*/
|
||||
inline std::string toString() const {
|
||||
if (m_ptr == NULL)
|
||||
return "ref<null>[]";
|
||||
return formatString("ref<%s>[null]",
|
||||
T::m_theClass->getName().c_str());
|
||||
else
|
||||
return formatString("ref<%s>[ref=%i, ptr=%s]",
|
||||
m_ptr->getClass()->getName().c_str(),
|
||||
|
|
|
@ -15,6 +15,7 @@ plugins += env.SharedLibrary('twosided', ['twosided.cpp'])
|
|||
plugins += env.SharedLibrary('mask', ['mask.cpp'])
|
||||
plugins += env.SharedLibrary('mixture', ['mixture.cpp'])
|
||||
plugins += env.SharedLibrary('coating', ['coating.cpp'])
|
||||
plugins += env.SharedLibrary('bump', ['bump.cpp'])
|
||||
|
||||
# Other materials
|
||||
plugins += env.SharedLibrary('ward', ['ward.cpp'])
|
||||
|
|
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include <mitsuba/render/scene.h>
|
||||
#include <mitsuba/hw/basicshader.h>
|
||||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/*! \plugin{bump}{Bump map}
|
||||
*
|
||||
* \parameters{
|
||||
* \parameter{\Unnamed}{\Texture}{
|
||||
* The luminance of this texture specifies the amount of
|
||||
* displacement. The implementation ignores any constant
|
||||
* offset---only changes in the luminance matter.
|
||||
* }
|
||||
* \parameter{\Unnamed}{\BSDF}{A BSDF model that should
|
||||
* be affected by the bump map}
|
||||
* }
|
||||
*
|
||||
* Bump mapping \cite{Blinn1978Simulation} is a simple technique for cheaply
|
||||
* adding surface detail to a rendering. This is done by perturbing the
|
||||
* shading coordinate frame based on a displacement height field provided
|
||||
* as a texture. This method can lend objects a highly realistic and detailed
|
||||
* appearance (e.g. wrinkled or covered by scratches and other imperfections)
|
||||
* without requiring any changes to the input geometry.
|
||||
*
|
||||
* The implementation in Mitsuba uses the common approach of ignoring
|
||||
* the normally negligible texture-space derivative of the base mesh
|
||||
* surface normal. As side effect of this decision, it is invariant
|
||||
* to constant offsets in the height field texture---only variations in
|
||||
* its luminance cause changes to the shading frame.
|
||||
*
|
||||
* Note that the magnitude of the height field variations influences
|
||||
* the strength of the displacement. If necessary, the \pluginref{scale}
|
||||
* texture plugin can be used to magnify the scale of an existing bump map.
|
||||
* \vspace{1cm}
|
||||
* \begin{xml}[caption=A rough metal model with a scaled image-based bump map]
|
||||
* <bsdf type="bump">
|
||||
* <!-- The bump map is applied to a rough metal BRDF -->
|
||||
* <bsdf type="roughconductor"/>
|
||||
*
|
||||
* <texture name="scale">
|
||||
* <!-- The scale of the displacement gets multiplied by 10x -->
|
||||
* <float name="scale" value="10"/>
|
||||
*
|
||||
* <texture name="bitmap">
|
||||
* <string name="filename" value="bumpmap.png"/>
|
||||
* </texture>
|
||||
* </texture>
|
||||
* </bsdf>
|
||||
* \end{xml}
|
||||
*/
|
||||
class BumpMap : public BSDF {
|
||||
public:
|
||||
BumpMap(const Properties &props) : BSDF(props) { }
|
||||
|
||||
BumpMap(Stream *stream, InstanceManager *manager)
|
||||
: BSDF(stream, manager) {
|
||||
m_nested = static_cast<BSDF *>(manager->getInstance(stream));
|
||||
m_displacement = static_cast<Texture *>(manager->getInstance(stream));
|
||||
configure();
|
||||
}
|
||||
|
||||
void configure() {
|
||||
if (!m_nested)
|
||||
Log(EError, "A child BSDF instance is required");
|
||||
if (!m_displacement)
|
||||
Log(EError, "A displacement texture must be specified");
|
||||
|
||||
m_components.clear();
|
||||
for (int i=0; i<m_nested->getComponentCount(); ++i)
|
||||
m_components.push_back(m_nested->getType(i) | ESpatiallyVarying | EAnisotropic);
|
||||
|
||||
m_usesRayDifferentials = true;
|
||||
|
||||
BSDF::configure();
|
||||
}
|
||||
|
||||
void serialize(Stream *stream, InstanceManager *manager) const {
|
||||
BSDF::serialize(stream, manager);
|
||||
|
||||
manager->serialize(stream, m_nested.get());
|
||||
manager->serialize(stream, m_displacement.get());
|
||||
}
|
||||
|
||||
void addChild(const std::string &name, ConfigurableObject *child) {
|
||||
if (child->getClass()->derivesFrom(MTS_CLASS(BSDF))) {
|
||||
if (m_nested != NULL)
|
||||
Log(EError, "Only a single nested BSDF can be added!");
|
||||
m_nested = static_cast<BSDF *>(child);
|
||||
} else if (child->getClass()->derivesFrom(MTS_CLASS(Texture))) {
|
||||
if (m_displacement != NULL)
|
||||
Log(EError, "Only a single displacement texture can be specified!");
|
||||
m_displacement = static_cast<Texture *>(child);
|
||||
} else {
|
||||
BSDF::addChild(name, child);
|
||||
}
|
||||
}
|
||||
|
||||
void perturbIntersection(const Intersection &its, Intersection &target) const {
|
||||
/* Determine the step size for the finite difference computation */
|
||||
Float du = 0.5f * std::abs(its.dudx) + std::abs(its.dudy),
|
||||
dv = 0.5f * std::abs(its.dvdx) + std::abs(its.dvdy);
|
||||
if (du == 0) du = Epsilon;
|
||||
if (dv == 0) dv = Epsilon;
|
||||
|
||||
/* Compute the U and V displacementment derivatives */
|
||||
Float displacement, displacementU, displacementV;
|
||||
target = its;
|
||||
displacement = m_displacement->getValue(target).getLuminance();
|
||||
target.p = its.p + its.dpdu * du;
|
||||
target.uv = its.uv + Point2(du, 0);
|
||||
displacementU = m_displacement->getValue(target).getLuminance();
|
||||
target.p = its.p + its.dpdv * dv;
|
||||
target.uv = its.uv + Point2(0, dv);
|
||||
displacementV = m_displacement->getValue(target).getLuminance();
|
||||
target.p = its.p;
|
||||
target.uv = its.uv;
|
||||
Float dDisplaceDu = (displacementU - displacement) / du;
|
||||
Float dDisplaceDv = (displacementV - displacement) / dv;
|
||||
|
||||
/* Build a perturbed frame -- ignores the usually
|
||||
negligible normal derivative term */
|
||||
Vector dpdu = its.dpdu + its.shFrame.n * (
|
||||
dDisplaceDu - dot(its.shFrame.n, its.dpdu));
|
||||
Vector dpdv = its.dpdv + its.shFrame.n * (
|
||||
dDisplaceDv - dot(its.shFrame.n, its.dpdv));
|
||||
|
||||
dpdu = normalize(dpdu);
|
||||
dpdv = normalize(dpdv - dpdu * dot(dpdv, dpdu));
|
||||
|
||||
target.shFrame.s = dpdu;
|
||||
target.shFrame.t = dpdv;
|
||||
target.shFrame = Frame(Normal(cross(dpdv, dpdu)));
|
||||
|
||||
if (dot(target.shFrame.n, target.geoFrame.n) < 0)
|
||||
target.shFrame.n *= -1;
|
||||
}
|
||||
|
||||
Spectrum eval(const BSDFQueryRecord &bRec, EMeasure measure) const {
|
||||
const Intersection& its = bRec.its;
|
||||
Intersection perturbed;
|
||||
perturbIntersection(its, perturbed);
|
||||
|
||||
BSDFQueryRecord perturbedQuery(perturbed,
|
||||
perturbed.toLocal(its.toWorld(bRec.wi)),
|
||||
perturbed.toLocal(its.toWorld(bRec.wo)), bRec.quantity);
|
||||
if (Frame::cosTheta(bRec.wo) * Frame::cosTheta(perturbedQuery.wo) <= 0)
|
||||
return Spectrum(0.0f);
|
||||
perturbedQuery.sampler = bRec.sampler;
|
||||
perturbedQuery.typeMask = bRec.typeMask;
|
||||
perturbedQuery.component = bRec.component;
|
||||
return m_nested->eval(perturbedQuery, measure);
|
||||
}
|
||||
|
||||
Float pdf(const BSDFQueryRecord &bRec, EMeasure measure) const {
|
||||
const Intersection& its = bRec.its;
|
||||
Intersection perturbed;
|
||||
perturbIntersection(its, perturbed);
|
||||
|
||||
BSDFQueryRecord perturbedQuery(perturbed,
|
||||
perturbed.toLocal(its.toWorld(bRec.wi)),
|
||||
perturbed.toLocal(its.toWorld(bRec.wo)), bRec.quantity);
|
||||
if (Frame::cosTheta(bRec.wo) * Frame::cosTheta(perturbedQuery.wo) <= 0)
|
||||
return 0;
|
||||
perturbedQuery.quantity = bRec.quantity;
|
||||
perturbedQuery.sampler = bRec.sampler;
|
||||
perturbedQuery.typeMask = bRec.typeMask;
|
||||
perturbedQuery.component = bRec.component;
|
||||
return m_nested->pdf(perturbedQuery, measure);
|
||||
}
|
||||
|
||||
Spectrum sample(BSDFQueryRecord &bRec, Float &pdf, const Point2 &sample) const {
|
||||
const Intersection& its = bRec.its;
|
||||
Intersection perturbed;
|
||||
perturbIntersection(its, perturbed);
|
||||
|
||||
BSDFQueryRecord perturbedQuery(perturbed, bRec.quantity);
|
||||
perturbedQuery.wi = perturbed.toLocal(its.toWorld(bRec.wi));
|
||||
perturbedQuery.sampler = bRec.sampler;
|
||||
perturbedQuery.typeMask = bRec.typeMask;
|
||||
perturbedQuery.component = bRec.component;
|
||||
Spectrum result = m_nested->sample(perturbedQuery, pdf, sample);
|
||||
|
||||
if (!result.isZero()) {
|
||||
bRec.sampledComponent = perturbedQuery.sampledComponent;
|
||||
bRec.sampledType = perturbedQuery.sampledType;
|
||||
bRec.wo = its.toLocal(perturbed.toWorld(perturbedQuery.wo));
|
||||
if (Frame::cosTheta(bRec.wo) * Frame::cosTheta(perturbedQuery.wo) <= 0)
|
||||
return Spectrum(0.0f);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Spectrum sample(BSDFQueryRecord &bRec, const Point2 &sample) const {
|
||||
const Intersection& its = bRec.its;
|
||||
Intersection perturbed;
|
||||
perturbIntersection(its, perturbed);
|
||||
|
||||
BSDFQueryRecord perturbedQuery(perturbed, bRec.quantity);
|
||||
perturbedQuery.wi = perturbed.toLocal(its.toWorld(bRec.wi));
|
||||
perturbedQuery.sampler = bRec.sampler;
|
||||
perturbedQuery.typeMask = bRec.typeMask;
|
||||
perturbedQuery.component = bRec.component;
|
||||
Spectrum result = m_nested->sample(perturbedQuery, sample);
|
||||
if (!result.isZero()) {
|
||||
bRec.sampledComponent = perturbedQuery.sampledComponent;
|
||||
bRec.sampledType = perturbedQuery.sampledType;
|
||||
bRec.wo = its.toLocal(perturbed.toWorld(perturbedQuery.wo));
|
||||
if (Frame::cosTheta(bRec.wo) * Frame::cosTheta(perturbedQuery.wo) <= 0)
|
||||
return Spectrum(0.0f);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Shader *createShader(Renderer *renderer) const;
|
||||
|
||||
std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
oss << "BumpMap[" << endl
|
||||
<< " name = \"" << getName() << "\"," << endl
|
||||
<< " displacement = " << indent(m_displacement->toString()) << endl
|
||||
<< " nested = " << indent(m_nested->toString()) << endl
|
||||
<< "]";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
protected:
|
||||
ref<Texture> m_displacement;
|
||||
ref<BSDF> m_nested;
|
||||
};
|
||||
|
||||
// ================ Hardware shader implementation ================
|
||||
|
||||
/**
|
||||
* This is a quite approximate version of the bump map model -- it likely
|
||||
* won't match the reference exactly, but it should be good enough for
|
||||
* preview purposes
|
||||
*/
|
||||
class BumpMapShader : public Shader {
|
||||
public:
|
||||
BumpMapShader(Renderer *renderer, const BSDF *nested, const Texture *displacement)
|
||||
: Shader(renderer, EBSDFShader), m_nested(nested), m_displacement(displacement) {
|
||||
m_nestedShader = renderer->registerShaderForResource(m_nested.get());
|
||||
m_displacementShader = renderer->registerShaderForResource(m_displacement.get());
|
||||
}
|
||||
|
||||
bool isComplete() const {
|
||||
return m_nestedShader.get() != NULL;
|
||||
}
|
||||
|
||||
void cleanup(Renderer *renderer) {
|
||||
renderer->unregisterShaderForResource(m_nested.get());
|
||||
renderer->unregisterShaderForResource(m_displacement.get());
|
||||
}
|
||||
|
||||
void putDependencies(std::vector<Shader *> &deps) {
|
||||
deps.push_back(m_nestedShader.get());
|
||||
deps.push_back(m_displacementShader.get());
|
||||
}
|
||||
|
||||
void generateCode(std::ostringstream &oss,
|
||||
const std::string &evalName,
|
||||
const std::vector<std::string> &depNames) const {
|
||||
oss << "vec3 " << evalName << "(vec2 uv, vec3 wi, vec3 wo) {" << endl
|
||||
<< " float du = abs(dFdx(uv.x)), dv = abs(dFdx(uv.y));" << endl
|
||||
<< " if (du == 0.0) du = 0.001;" << endl
|
||||
<< " if (dv == 0.0) dv = 0.001;" << endl
|
||||
<< " float displacement = " << depNames[1] << "(uv)[0];" << endl
|
||||
<< " float displacementU = " << depNames[1] << "(uv + vec2(du, 0.0))[0];" << endl
|
||||
<< " float displacementV = " << depNames[1] << "(uv + vec2(0.0, dv))[0];" << endl
|
||||
<< " float dfdu = (displacementU - displacement)/du;" << endl
|
||||
<< " float dfdv = (displacementV - displacement)/dv;" << endl
|
||||
<< " vec3 dpdu = normalize(vec3(1.0, 0.0, dfdu));" << endl
|
||||
<< " vec3 dpdv = vec3(0.0, 1.0, dfdv);" << endl
|
||||
<< " dpdv = normalize(dpdv - dot(dpdu, dpdv)*dpdu);" << endl
|
||||
<< " vec3 n = cross(dpdu, dpdv);" << endl
|
||||
<< " wi = vec3(dot(wi, dpdu), dot(wi, dpdv), dot(wi, n));" << endl
|
||||
<< " wo = vec3(dot(wo, dpdu), dot(wo, dpdv), dot(wo, n));" << endl
|
||||
<< " return " << depNames[0] << "(uv, wi, wo);" << endl
|
||||
<< "}" << endl
|
||||
<< endl
|
||||
<< "vec3 " << evalName << "_diffuse(vec2 uv, vec3 wi, vec3 wo) {" << endl
|
||||
<< " return " << depNames[0] << "_diffuse(uv, wi, wo);" << endl
|
||||
<< "}" << endl;
|
||||
}
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
private:
|
||||
ref<const BSDF> m_nested;
|
||||
ref<const Texture> m_displacement;
|
||||
ref<Shader> m_nestedShader;
|
||||
ref<Shader> m_displacementShader;
|
||||
};
|
||||
|
||||
Shader *BumpMap::createShader(Renderer *renderer) const {
|
||||
return new BumpMapShader(renderer, m_nested.get(), m_displacement.get());
|
||||
}
|
||||
|
||||
MTS_IMPLEMENT_CLASS(BumpMapShader, false, Shader)
|
||||
MTS_IMPLEMENT_CLASS_S(BumpMap, false, BSDF)
|
||||
MTS_EXPORT_PLUGIN(BumpMap, "Smooth dielectric coating");
|
||||
MTS_NAMESPACE_END
|
|
@ -30,8 +30,9 @@ MTS_NAMESPACE_BEGIN
|
|||
* 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{thickness}{\Float}{Denotes the thickness of the absorbing layer (given in inverse units of \code{sigmaA})\default{1}}
|
||||
* \parameter{thickness}{\Float}{Denotes the thickness of the layer (to model absorption --- should be specified in inverse units of \code{sigmaA})\default{1}}
|
||||
* \parameter{sigmaA}{\Spectrum\Or\Texture}{The absorption coefficient of the coating layer. \default{0, i.e. there is no absorption}}
|
||||
* \parameter{\Unnamed}{\BSDF}{A nested BSDF model that should be coated.}
|
||||
* }
|
||||
*
|
||||
* \renderings{
|
||||
|
|
|
@ -37,7 +37,8 @@ MTS_NAMESPACE_BEGIN
|
|||
* \default{1.0}}
|
||||
* }
|
||||
* \renderings{
|
||||
* \rendering{Measured copper material (the default)}
|
||||
* \rendering{Measured copper material (the default), rendered using 30
|
||||
* spectral samples between 360 and 830$nm$}
|
||||
* {bsdf_conductor_copper.jpg}
|
||||
* \rendering{Measured gold material (\lstref{conductor-gold})}
|
||||
* {bsdf_conductor_gold.jpg}
|
||||
|
@ -45,14 +46,14 @@ MTS_NAMESPACE_BEGIN
|
|||
*
|
||||
* This plugin implements a perfectly smooth interface to a conducting material,
|
||||
* such as a metal. For a similar model that instead describes a rough surface
|
||||
* microstructure, take a look at the seperately available
|
||||
* microstructure, take a look at the separately available
|
||||
* \pluginref{roughconductor} plugin.
|
||||
|
||||
* In contrast to dielectric materials, conductors do not transmit
|
||||
* any light. Their index of refraction is complex-valued and tends to undergo
|
||||
* considerable changes throughout the visible color spectrum.
|
||||
*
|
||||
* To faciliate the tedious task of specifying spectrally-varying index of
|
||||
* To facilitate the tedious task of specifying spectrally-varying index of
|
||||
* refraction information, Mitsuba ships with a set of measured data for
|
||||
* several materials, where visible-spectrum information was publicly
|
||||
* available\footnote{
|
||||
|
@ -69,7 +70,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* 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
|
||||
* separate measurements corresponding to their two indices of
|
||||
* refraction (named ``ordinary'' and ``extraordinary ray'').
|
||||
*
|
||||
* When using this plugin, you should ideally compile Mitsuba with support for
|
||||
|
|
|
@ -65,7 +65,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* \end{xml}
|
||||
*
|
||||
* When using this model, it is crucial that the scene contains
|
||||
* meaningful and mutally compatible indices of refraction changes---see
|
||||
* meaningful and mutually compatible indices of refraction changes---see
|
||||
* \figref{glass-explanation} for a description of what this entails.
|
||||
*
|
||||
* In many cases, we will want to additionally describe the \emph{medium} within a
|
||||
|
@ -83,8 +83,8 @@ MTS_NAMESPACE_BEGIN
|
|||
* </bsdf>
|
||||
*
|
||||
* <medium type="homogeneous" name="interior">
|
||||
* <rgb name="sigmaS" value="0, 0, 0"/>
|
||||
* <rgb name="sigmaA" value="4, 4, 2"/>
|
||||
* <rgb name="sigmaS" value="0, 0, 0"/>
|
||||
* <rgb name="sigmaA" value="4, 4, 2"/>
|
||||
* </medium>
|
||||
* <shape>
|
||||
* \end{xml}
|
||||
|
|
|
@ -26,6 +26,8 @@ MTS_NAMESPACE_BEGIN
|
|||
* \parameter{opacity}{\Spectrum\Or\Texture}{
|
||||
* Specifies the per-channel opacity (where $1=$ completely transparent)\default{0.5}.
|
||||
* }
|
||||
* \parameter{\Unnamed}{\BSDF}{A base BSDF model that represents the
|
||||
* non-transparent portion of the scattering}
|
||||
* }
|
||||
* \renderings{
|
||||
* \rendering{Rendering without an opacity mask}
|
||||
|
@ -37,7 +39,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* between perfectly transparent and completely opaque based on the \code{opacity}
|
||||
* parameter.
|
||||
*
|
||||
* The transparency is implemented as a forward-facing Diract delta distribution.
|
||||
* The transparency is implemented as a forward-facing Dirac delta distribution.
|
||||
* \vspace{5mm}
|
||||
*
|
||||
* \begin{xml}[caption=Material configuration for a transparent leaf,
|
||||
|
|
|
@ -26,6 +26,8 @@ MTS_NAMESPACE_BEGIN
|
|||
*
|
||||
* \parameters{
|
||||
* \parameter{weights}{\String}{A comma-separated list of BSDF weights}
|
||||
* \parameter{\Unnamed}{\BSDF}{Multiple BSDF instances that should be
|
||||
* mixed according to the specified weights}
|
||||
* }
|
||||
* \renderings{
|
||||
* \rendering{An admittedly not particularly realistic linear combination of
|
||||
|
@ -37,7 +39,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* model in Mitsuba (be it smooth, rough, reflecting, or transmitting) can
|
||||
* be mixed with others in this manner to synthesize new models. There
|
||||
* is no limit on how many models can be mixed, but their combination
|
||||
* weights must be nonnegative and sum to less than one to ensure
|
||||
* weights must be non-negative and sum to a value of one or less to ensure
|
||||
* energy balance.
|
||||
*
|
||||
* \vspace{4mm}
|
||||
|
|
|
@ -46,7 +46,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* \end{enumerate}
|
||||
* }
|
||||
* \parameter{alpha}{\Float\Or\Texture}{
|
||||
* Specifies the roughness of the unresolved surface microgeometry.
|
||||
* Specifies the roughness of the unresolved surface micro-geometry.
|
||||
* When the Beckmann distribution is used, this parameter is equal to the
|
||||
* \emph{root mean square} (RMS) slope of the microfacets. This
|
||||
* parameter is only valid when \texttt{distribution=beckmann/phong/ggx}.
|
||||
|
@ -97,7 +97,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* for Refraction through Rough Surfaces'' by Walter et al.
|
||||
* \cite{Walter07Microfacet}. It supports several different types of microfacet
|
||||
* distributions and has a texturable roughness parameter.
|
||||
* To faciliate the tedious task of specifying spectrally-varying index of
|
||||
* To facilitate the tedious task of specifying spectrally-varying index of
|
||||
* refraction information, this plugin can access a set of measured materials
|
||||
* for which visible-spectrum information was publicly available
|
||||
* (see \tblref{conductor-iors} for the full list).
|
||||
|
@ -114,7 +114,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* and $\alpha=0.3-0.7$ is \emph{extremely} rough (e.g. an etched or ground
|
||||
* finish). Values significantly above that are probably not too realistic.
|
||||
* \vspace{-6mm}
|
||||
* \subsubsection*{Techical details}\vspace{-2mm}
|
||||
* \subsubsection*{Technical details}\vspace{-2mm}
|
||||
* When rendering with the Ashikhmin-Shirley or Phong microfacet
|
||||
* distributions, a conversion is used to turn the specified
|
||||
* $\alpha$ roughness value into the exponents of these distributions.
|
||||
|
|
|
@ -52,7 +52,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* \end{enumerate}
|
||||
* }
|
||||
* \parameter{alpha}{\Float\Or\Texture}{
|
||||
* Specifies the roughness of the unresolved surface microgeometry.
|
||||
* Specifies the roughness of the unresolved surface micro-geometry.
|
||||
* When the Beckmann distribution is used, this parameter is equal to the
|
||||
* \emph{root mean square} (RMS) slope of the microfacets. This
|
||||
* parameter is only valid when \texttt{distribution=beckmann/phong/ggx}.
|
||||
|
@ -115,7 +115,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* finish).
|
||||
*
|
||||
* Please note that when using this plugin, it is crucial that the scene contains
|
||||
* meaningful and mutally compatible index of refraction changes---see
|
||||
* meaningful and mutually compatible index of refraction changes---see
|
||||
* \figref{glass-explanation} for an example of what this entails. Also, note that
|
||||
* the importance sampling implementation of this model is close, but
|
||||
* not always a perfect a perfect match to the underlying scattering distribution,
|
||||
|
@ -123,7 +123,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* microfacet distribution is used. Hence, such renderings may
|
||||
* converge slowly.
|
||||
*
|
||||
* \subsubsection*{Techical details}
|
||||
* \subsubsection*{Technical details}
|
||||
* When rendering with the Ashikhmin-Shirley or Phong microfacet
|
||||
* distributions, a conversion is used to turn the specified
|
||||
* $\alpha$ roughness value into the exponents of these distributions.
|
||||
|
|
|
@ -29,7 +29,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* material. \default{0.5}
|
||||
* }
|
||||
* \parameter{alpha}{\Spectrum\Or\Texture}{
|
||||
* Specifies the roughness of the unresolved surface microgeometry
|
||||
* Specifies the roughness of the unresolved surface micro-geometry
|
||||
* using the \emph{root mean square} (RMS) slope of the
|
||||
* microfacets. \default{0.2}
|
||||
* }
|
||||
|
@ -64,9 +64,9 @@ MTS_NAMESPACE_BEGIN
|
|||
* to Lambertian scattering, which does not take surface roughness into account.
|
||||
*
|
||||
* The implementation in Mitsuba uses a surface roughness parameter $\alpha$ that
|
||||
* is slighly different from the slope-area variance in the original 1994 paper.
|
||||
* is slightly different from the slope-area variance in the original 1994 paper.
|
||||
* The reason for this change is to make the parameter $\alpha$ portable
|
||||
* across different models (i.e. \pluginref{roughglass}, \pluginref{roughplastic},
|
||||
* across different models (i.e. \pluginref{roughdielectric}, \pluginref{roughplastic},
|
||||
* \pluginref{roughconductor}).
|
||||
*
|
||||
* To get an intuition about the effect of the
|
||||
|
|
|
@ -47,7 +47,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* \end{enumerate}
|
||||
* }
|
||||
* \parameter{alpha}{\Float}{
|
||||
* Specifies the roughness of the unresolved surface microgeometry.
|
||||
* Specifies the roughness of the unresolved surface micro-geometry.
|
||||
* When the Beckmann distribution is used, this parameter is equal to the
|
||||
* \emph{root mean square} (RMS) slope of the microfacets.
|
||||
* \default{0.1}.
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/*!\plugin{twosided}{Two-sided BRDF adapter}
|
||||
* \parameters{
|
||||
* \parameter{\Unnamed}{\BSDF}{A nested BRDF that should
|
||||
* be turned into a two-sided scattering model.}
|
||||
* }
|
||||
*
|
||||
* \renderings{
|
||||
* \unframedrendering{From this angle, the Cornell box scene shows visible back-facing geometry}
|
||||
* {bsdf_twosided_before}
|
||||
|
|
|
@ -85,7 +85,7 @@ Texture *BSDF::ensureEnergyConservation(Texture *texture,
|
|||
<< "to the BSDF to prevent this from happening.";
|
||||
Log(EWarn, "%s", oss.str().c_str());
|
||||
Properties props("scale");
|
||||
props.setFloat("value", scale);
|
||||
props.setFloat("scale", scale);
|
||||
Texture *scaleTexture = static_cast<Texture *> (PluginManager::getInstance()->
|
||||
createObject(MTS_CLASS(Texture), props));
|
||||
scaleTexture->addChild("", texture);
|
||||
|
@ -150,7 +150,9 @@ static std::string typeMaskToString(unsigned int typeMask) {
|
|||
if (isset(BSDF::EFrontSide)) { oss << "frontSide "; typeMask &= ~BSDF::EFrontSide; }
|
||||
if (isset(BSDF::EBackSide)) { oss << "backSide "; typeMask &= ~BSDF::EBackSide; }
|
||||
if (isset(BSDF::ECanUseSampler)) { oss << "canUseSampler "; typeMask &= ~BSDF::ECanUseSampler; }
|
||||
if (isset(BSDF::ESpatiallyVarying)) { oss << "spatiallyVarying"; typeMask &= ~BSDF::ESpatiallyVarying; }
|
||||
#undef isset
|
||||
SAssert(typeMask == 0);
|
||||
oss << "}";
|
||||
return oss.str();
|
||||
}
|
||||
|
|
|
@ -78,18 +78,22 @@ std::string Intersection::toString() const {
|
|||
if (!isValid())
|
||||
return "Intersection[invalid]";
|
||||
std::ostringstream oss;
|
||||
oss << "Intersection[" << std::endl
|
||||
<< " p = " << p.toString() << "," << std::endl
|
||||
<< " wi = " << wi.toString() << "," << std::endl
|
||||
<< " t = " << t << "," << std::endl
|
||||
<< " geoFrame = " << indent(geoFrame.toString()) << "," << std::endl
|
||||
<< " shFrame = " << indent(shFrame.toString()) << "," << std::endl
|
||||
<< " uv = " << uv.toString() << "," << std::endl
|
||||
<< " hasUVPartials = " << hasUVPartials << "," << std::endl
|
||||
<< " dpdu = " << dpdu.toString() << "," << std::endl
|
||||
<< " dpdv = " << dpdv.toString() << "," << std::endl
|
||||
<< " time = " << time << "," << std::endl
|
||||
<< " shape = " << indent(((Object *)shape)->toString()) << std::endl
|
||||
oss << "Intersection[" << endl
|
||||
<< " p = " << p.toString() << "," << endl
|
||||
<< " wi = " << wi.toString() << "," << endl
|
||||
<< " t = " << t << "," << endl
|
||||
<< " geoFrame = " << indent(geoFrame.toString()) << "," << endl
|
||||
<< " shFrame = " << indent(shFrame.toString()) << "," << endl
|
||||
<< " uv = " << uv.toString() << "," << endl
|
||||
<< " hasUVPartials = " << hasUVPartials << "," << endl
|
||||
<< " dpdu = " << dpdu.toString() << "," << endl
|
||||
<< " dpdv = " << dpdv.toString() << "," << endl;
|
||||
if (hasUVPartials) {
|
||||
oss << " dud[x,y] = [" << dudx << ", " << dudy << "]," << endl
|
||||
<< " dvd[x,y] = [" << dvdx << ", " << dvdy << "]," << endl;
|
||||
}
|
||||
oss << " time = " << time << "," << endl
|
||||
<< " shape = " << indent(((Object *)shape)->toString()) << endl
|
||||
<< "]";
|
||||
return oss.str();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <mitsuba/render/renderjob.h>
|
||||
#include <mitsuba/core/timer.h>
|
||||
#include <mitsuba/core/mstream.h>
|
||||
#include <mitsuba/core/fstream.h>
|
||||
#include <mitsuba/hw/font.h>
|
||||
|
||||
GLWidget::GLWidget(QWidget *parent) :
|
||||
|
@ -1060,6 +1061,14 @@ void GLWidget::paintGL() {
|
|||
m_luminanceProgram->unbind();
|
||||
buffer->unbind();
|
||||
m_luminanceBuffer[0]->releaseTarget();
|
||||
#if 0
|
||||
/* For debugging .. */
|
||||
ref<Bitmap> bitmap = new Bitmap(size.x, size.y, 128);
|
||||
m_luminanceBuffer[0]->download(bitmap);
|
||||
ref<FileStream> fs = new FileStream("test.exr", FileStream::ETruncReadWrite);
|
||||
bitmap->save(Bitmap::EEXR, fs);
|
||||
fs->close();
|
||||
#endif
|
||||
|
||||
/* Iteratively downsample the image until left with a 1x1 pixel sum over
|
||||
the whole image */
|
||||
|
|
|
@ -1314,13 +1314,15 @@ void MainWindow::onExportDialogClose(int reason) {
|
|||
for (int y=0; y<height; ++y) {
|
||||
for (int x=0; x<width; ++x) {
|
||||
Spectrum spec;
|
||||
spec.fromLinearRGB(source[(y*width+x)*4+0], source[(y*width+x)*4+1], source[(y*width+x)*4+2]);
|
||||
spec.fromLinearRGB(source[(y*width+x)*4+0],
|
||||
source[(y*width+x)*4+1], source[(y*width+x)*4+2]);
|
||||
avgLogLuminance += std::log(0.001f+spec.getLuminance());
|
||||
}
|
||||
}
|
||||
avgLogLuminance = std::exp(avgLogLuminance/(width*height));
|
||||
reinhardKey = ctx->reinhardKey / avgLogLuminance;
|
||||
}
|
||||
|
||||
|
||||
for (int y=0; y<height; ++y) {
|
||||
for (int x=0; x<width; ++x) {
|
||||
|
|
|
@ -99,15 +99,20 @@ public:
|
|||
: m_bsdf(bsdf), m_sampler(sampler), m_wi(wi), m_component(component),
|
||||
m_largestWeight(0), m_passSamplerToBSDF(passSamplerToBSDF) {
|
||||
m_fakeSampler = new FakeSampler(m_sampler);
|
||||
m_its.uv = Point2(0.0f);
|
||||
m_its.dpdu = Vector(1, 0, 0);
|
||||
m_its.dpdv = Vector(0, 1, 0);
|
||||
m_its.dudx = m_its.dvdy = 0.01f;
|
||||
m_its.dudy = m_its.dvdx = 0.00f;
|
||||
m_its.shFrame = Frame(Normal(0, 0, 1));
|
||||
}
|
||||
|
||||
boost::tuple<Vector, Float, EMeasure> generateSample() {
|
||||
Point2 sample(m_sampler->next2D());
|
||||
Intersection its;
|
||||
BSDFQueryRecord bRec(its);
|
||||
BSDFQueryRecord bRec(m_its);
|
||||
bRec.component = m_component;
|
||||
bRec.wi = m_wi;
|
||||
|
||||
|
||||
#if defined(MTS_DEBUG_FP)
|
||||
enableFPExceptions();
|
||||
#endif
|
||||
|
@ -187,8 +192,7 @@ public:
|
|||
}
|
||||
|
||||
Float pdf(const Vector &wo, EMeasure measure) {
|
||||
Intersection its;
|
||||
BSDFQueryRecord bRec(its);
|
||||
BSDFQueryRecord bRec(m_its);
|
||||
bRec.component = m_component;
|
||||
bRec.wi = m_wi;
|
||||
bRec.wo = wo;
|
||||
|
@ -212,6 +216,7 @@ public:
|
|||
|
||||
inline Float getLargestWeight() const { return m_largestWeight; }
|
||||
private:
|
||||
Intersection m_its;
|
||||
ref<const BSDF> m_bsdf;
|
||||
ref<Sampler> m_sampler;
|
||||
ref<FakeSampler> m_fakeSampler;
|
||||
|
|
|
@ -31,10 +31,10 @@ MTS_NAMESPACE_BEGIN
|
|||
class ScalingTexture : public Texture {
|
||||
public:
|
||||
ScalingTexture(const Properties &props) : Texture(props) {
|
||||
if (props.hasProperty("value") && props.getType("value") == Properties::EFloat)
|
||||
m_scale = Spectrum(props.getFloat("value", 1.0f));
|
||||
if (props.hasProperty("scale") && props.getType("scale") == Properties::EFloat)
|
||||
m_scale = Spectrum(props.getFloat("scale", 1.0f));
|
||||
else
|
||||
m_scale = props.getSpectrum("value", Spectrum(1.0f));
|
||||
m_scale = props.getSpectrum("scale", Spectrum(1.0f));
|
||||
}
|
||||
|
||||
ScalingTexture(Stream *stream, InstanceManager *manager)
|
||||
|
|
Loading…
Reference in New Issue