You are on page 1of 84

9/12/2016

mitApi

C:\Users\sys\Desktop\Nuevacarpeta\salida\salida25\subsalida1_25\mitsubaapi

https://raw.githubusercontent.com/mmanzi/gradientdomain
mitsuba/7f01a2c044440c774dd88afe05eea4acdc418f2c/src/bsdfs/diffuse.cpp

#include<mitsuba/render/bsdf.h>
#include<mitsuba/render/texture.h>
#include<mitsuba/hw/basicshader.h>
#include<mitsuba/core/warp.h>

MTS_NAMESPACE_BEGIN
/*!\plugin{diffuse}{Smoothdiffusematerial}
*\order{1}
*\icon{bsdf_diffuse}
*\parameters{
*\parameter{reflectance}{\Spectrum\Or\Texture}{
*Specifiesthediffusealbedoofthe
*material\default{0.5}
*}
*}
*
*\renderings{
*\rendering{Homogeneousreflectance,see\lstref{diffuseuniform}}
*{bsdf_diffuse_plain}
*\rendering{Texturedreflectance,see\lstref{diffusetextured}}
*{bsdf_diffuse_textured}
*}
*
*Thesmoothdiffusematerial(alsoreferredtoas``Lambertian'')
*representsanideallydiffusematerialwithauserspecifiedamountof
*reflectance.Anyreceivedilluminationisscatteredsothatthesurface
*looksthesameindependentlyofthedirectionofobservation.
*
*Apartfromahomogeneousreflectancevalue,theplugincanalsoaccept
*anestedorreferencedtexturemaptobeusedasthesourceofreflectance
*information,whichisthenmappedontotheshapebasedonitsUV
*parameterization.Whennoparametersarespecified,themodelusesthedefault
*of50%reflectance.
*
*Notethatthismaterialisonesidedthatis,observedfromthe
*backside,itwillbecompletelyblack.Ifthisisundesirable,
*considerusingthe\pluginref{twosided}BRDFadapterplugin.
*\vspace{4mm}
*
*\begin{xml}[caption={Adiffusematerial,whosereflectanceisspecified
*asansRGBcolor},label=lst:diffuseuniform]
*<bsdftype="diffuse">
*<srgbname="reflectance"value="#6d7185"/>
*</bsdf>
*\end{xml}
*
*\begin{xml}[caption=Adiffusematerialwithatexturemap,
*label=lst:diffusetextured]
*<bsdftype="diffuse">
*<texturetype="bitmap"name="reflectance">
*<stringname="filename"value="wood.jpg"/>
*</texture>
*</bsdf>
*\end{xml}
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

1/84

9/12/2016

mitApi

*/
classSmoothDiffuse:publicBSDF{
public:

SmoothDiffuse(constProperties&props)

:BSDF(props){

/*Forbettercompatibilitywithothermodels,supportboth

'reflectance'and'diffuseReflectance'asparameternames*/

m_reflectance=newConstantSpectrumTexture(props.getSpectrum(

props.hasProperty("reflectance")?"reflectance"

:"diffuseReflectance",Spectrum(.5f)));

SmoothDiffuse(Stream*stream,InstanceManager*manager)

:BSDF(stream,manager){

m_reflectance=static_cast<Texture*>(manager>getInstance(stream));

voidconfigure(){

/*Verifytheinputparameterandfixthemifnecessary*/

m_reflectance=ensureEnergyConservation(m_reflectance,"reflectance",1.0f);

m_components.clear();
if(m_reflectance>getMaximum().max()>0)

m_components.push_back(EDiffuseReflection|EFrontSide

|(m_reflectance>isConstant()?0:ESpatiallyVarying));

m_usesRayDifferentials=m_reflectance>usesRayDifferentials();

BSDF::configure();

SpectrumgetDiffuseReflectance(constIntersection&its)const{

returnm_reflectance>eval(its);
}

Spectrumeval(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

if(!(bRec.typeMask&EDiffuseReflection)||measure!=ESolidAngle

||Frame::cosTheta(bRec.wi)<=0

||Frame::cosTheta(bRec.wo)<=0)

returnSpectrum(0.0f);

Floatpdf(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

if(!(bRec.typeMask&EDiffuseReflection)||measure!=ESolidAngle

||Frame::cosTheta(bRec.wi)<=0

||Frame::cosTheta(bRec.wo)<=0)

return0.0f;

Spectrumsample(BSDFSamplingRecord&bRec,constPoint2&sample)const{

if(!(bRec.typeMask&EDiffuseReflection)||Frame::cosTheta(bRec.wi)<=0)

returnSpectrum(0.0f);

Spectrumsample(BSDFSamplingRecord&bRec,Float&pdf,constPoint2&sample)const{

if(!(bRec.typeMask&EDiffuseReflection)||Frame::cosTheta(bRec.wi)<=0)

returnSpectrum(0.0f);

voidaddChild(conststd::string&name,ConfigurableObject*child){

if(child>getClass()>derivesFrom(MTS_CLASS(Texture))

configure();

returnm_reflectance>eval(bRec.its)

*(INV_PI*Frame::cosTheta(bRec.wo));

returnwarp::squareToCosineHemispherePdf(bRec.wo);

bRec.wo=warp::squareToCosineHemisphere(sample);
bRec.eta=1.0f;
bRec.sampledComponent=0;
bRec.sampledType=EDiffuseReflection;
returnm_reflectance>eval(bRec.its);

bRec.wo=warp::squareToCosineHemisphere(sample);
bRec.eta=1.0f;
bRec.sampledComponent=0;
bRec.sampledType=EDiffuseReflection;
pdf=warp::squareToCosineHemispherePdf(bRec.wo);
returnm_reflectance>eval(bRec.its);

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

2/84

9/12/2016

mitApi

&&(name=="reflectance"||name=="diffuseReflectance")){

m_reflectance=static_cast<Texture*>(child);
}else{

BSDF::addChild(name,child);
}

voidserialize(Stream*stream,InstanceManager*manager)const{

BSDF::serialize(stream,manager);

FloatgetRoughness(constIntersection&its,intcomponent)const{

returnstd::numeric_limits<Float>::infinity();
}

std::stringtoString()const{

std::ostringstreamoss;

oss<<"SmoothDiffuse["<<endl

<<"id=\""<<getID()<<"\","<<endl

<<"reflectance="<<indent(m_reflectance>toString())<<endl

<<"]";

returnoss.str();
}

Shader*createShader(Renderer*renderer)const;

manager>serialize(stream,m_reflectance.get());

MTS_DECLARE_CLASS()
private:

ref<Texture>m_reflectance;
};
//================Hardwareshaderimplementation================
classSmoothDiffuseShader:publicShader{
public:

SmoothDiffuseShader(Renderer*renderer,constTexture*reflectance)

:Shader(renderer,EBSDFShader),m_reflectance(reflectance){

m_reflectanceShader=renderer>registerShaderForResource(m_reflectance.get());

boolisComplete()const{

returnm_reflectanceShader.get()!=NULL;
}

voidcleanup(Renderer*renderer){

renderer>unregisterShaderForResource(m_reflectance.get());
}

voidputDependencies(std::vector<Shader*>&deps){

deps.push_back(m_reflectanceShader.get());
}

voidgenerateCode(std::ostringstream&oss,

conststd::string&evalName,

conststd::vector<std::string>&depNames)const{

oss<<"vec3"<<evalName<<"(vec2uv,vec3wi,vec3wo){"<<endl

<<"if(cosTheta(wi)<0.0||cosTheta(wo)<0.0)"<<endl

<<"
returnvec3(0.0);"<<endl

<<"return"<<depNames[0]<<"(uv)*inv_pi*cosTheta(wo);"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"_diffuse(vec2uv,vec3wi,vec3wo){"<<endl

<<"return"<<evalName<<"(uv,wi,wo);"<<endl

<<"}"<<endl;
}

MTS_DECLARE_CLASS()
private:

ref<constTexture>m_reflectance;

ref<Shader>m_reflectanceShader;
};
Shader*SmoothDiffuse::createShader(Renderer*renderer)const{

returnnewSmoothDiffuseShader(renderer,m_reflectance.get());
}
MTS_IMPLEMENT_CLASS(SmoothDiffuseShader,false,Shader)
MTS_IMPLEMENT_CLASS_S(SmoothDiffuse,false,BSDF)
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

3/84

9/12/2016

mitApi

MTS_EXPORT_PLUGIN(SmoothDiffuse,"SmoothdiffuseBRDF")
MTS_NAMESPACE_END

https://raw.githubusercontent.com/mmanzi/gradientdomain
mitsuba/7f01a2c044440c774dd88afe05eea4acdc418f2c/src/bsdfs/dielectric.cpp

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

4/84

9/12/2016

mitApi

#include<mitsuba/render/bsdf.h>
#include<mitsuba/hw/basicshader.h>
#include"ior.h"
MTS_NAMESPACE_BEGIN
/*!\plugin{dielectric}{Smoothdielectricmaterial}
*\order{3}
*\icon{bsdf_dielectric}
*\parameters{
*\parameter{intIOR}{\Float\Or\String}{Interiorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{bk7}/1.5046}}
*\parameter{extIOR}{\Float\Or\String}{Exteriorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{air}/1.000277}}
*\parameter{specular\showbreakReflectance}{\Spectrum\Or\Texture}{Optional
*factorthatcanbeusedtomodulatethespecularreflectioncomponent.Note
*thatforphysicalrealism,thisparametershouldneverbetouched.\default{1.0}}
*\parameter{specular\showbreakTransmittance}{\Spectrum\Or\Texture}{Optional
*factorthatcanbeusedtomodulatethespeculartransmissioncomponent.Note
*thatforphysicalrealism,thisparametershouldneverbetouched.\default{1.0}}
*}
*
*\renderings{
*\medrendering{Air$\leftrightarrow$Water(IOR:1.33)interface.
*See\lstref{dielectricwater}.}{bsdf_dielectric_water}
*\medrendering{Air$\leftrightarrow$Diamond(IOR:2.419)}{bsdf_dielectric_diamond}
*\medrendering{Air$\leftrightarrow$Glass(IOR:1.504)interfacewithabsorption.
*See\lstref{dielectricglass}.}{bsdf_dielectric_glass}
*}
*
*Thispluginmodelsaninterfacebetweentwodielectricmaterialshavingmismatched
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

5/84

9/12/2016

mitApi

*indicesofrefraction(forinstance,waterandair).ExteriorandinteriorIORvalues
*canbespecifiedindependently,where``exterior''referstothesidethatcontains
*thesurfacenormal.Whennoparametersaregiven,thepluginactivatesthedefaults,which
*describeaborosilicateglassBK7/airinterface.
*
*Inthismodel,themicroscopicstructureofthesurfaceisassumedtobeperfectly
*smooth,resultinginadegenerate\footnote{Meaningthatforanygivenincomingrayoflight,
*themodelalwaysscattersintoadiscretesetofdirections,asopposedtoacontinuum.}
*BSDFdescribedbyaDiracdeltadistribution.Forasimilarmodelthatinsteaddescribesa
*roughsurfacemicrostructure,takealookatthe\pluginref{roughdielectric}plugin.
*
*\begin{xml}[caption=Asimpleairtowaterinterface,label=lst:dielectricwater]
*<shapetype="...">
*<bsdftype="dielectric">
*<stringname="intIOR"value="water"/>
*<stringname="extIOR"value="air"/>
*</bsdf>
*<shape>
*\end{xml}
*
*Whenusingthismodel,itiscrucialthatthescenecontains
*meaningfulandmutuallycompatibleindicesofrefractionchangessee
*\figref{glassexplanation}foradescriptionofwhatthisentails.
*
*Inmanycases,wewillwanttoadditionallydescribethe\emph{medium}withina
*dielectricmaterial.Thisrequirestheuseofarenderingtechniquethatis
*awareofmedia(e.g.thevolumetricpathtracer).Anexampleofhowonemight
*describeaslightlyabsorbingpieceofglassisshownbelow:
*\begin{xml}[caption=Aglassmaterialwithabsorption(basedonthe
*BeerLambertlaw).Thismaterialcanonlybeusedbyanintegrator
*thatisawareofparticipatingmedia.,label=lst:dielectricglass]
*<shapetype="...">
*<bsdftype="dielectric">
*<floatname="intIOR"value="1.504"/>
*<floatname="extIOR"value="1.0"/>
*</bsdf>
*
*<mediumtype="homogeneous"name="interior">
*<rgbname="sigmaS"value="0,0,0"/>
*<rgbname="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\textbf{Name}&\multicolumn{2}{l}{\textbf{Value}}&&
*\rmfamily\textbf{Name}&\multicolumn{2}{l}{\textbf{Value}}\\
*\cmidrule{13}\cmidrule{57}
*vacuum&1&0&&
*bromine&1&661\\
*helium&1&00004&&
*waterice&1&31\\
*hydrogen&1&00013&&
*fusedquartz&1&458\\[.8mm]
*\cmidrule{57}\\[5.5mm]
*air&1&00028&&
*pyrex&1&470\\
*carbondioxide&1&00045&&
*acrylicglass&1&49\\[.8mm]
*\cmidrule{13}\\[5.5mm]
*water&1&3330&&
*polypropylene&1&49\\
*acetone&1&36&&
*bk7&1&5046\\
*ethanol&1&361&&
*sodiumchloride&1&544\\
*carbontetrachloride&1&461&&
*amber&1&55\\
*glycerol&1&4729&&
*pet&1&575\\
*benzene&1&501&&
*diamond&2&419\\
*siliconeoil&1&52045\\
*\bottomrule
*\end{tabular}
*\caption{
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

6/84

9/12/2016

mitApi

*\label{tbl:dielectriciors}
*Thistablelistsallsupportedmaterialnamesalongwith
*alongwiththeirassociatedindexofrefractionatstandard
*conditions.Thesematerialnamescanbeusedwiththeplugins
*\pluginref{dielectric},\
*\pluginref{roughdielectric},\
*\pluginref{plastic},\
*\pluginref{roughplastic},aswellas
*\pluginref{coating}.
*}
*\end{table}
*\remarks{
*\itemDispersioniscurrentlyunsupportedbutwillbeenabledinafuturerelease.
*}
*/
classSmoothDielectric:publicBSDF{
public:

SmoothDielectric(constProperties&props):BSDF(props){

/*Specifiestheinternalindexofrefractionattheinterface*/

FloatintIOR=lookupIOR(props,"intIOR","bk7");

/*Specifiestheexternalindexofrefractionattheinterface*/
FloatextIOR=lookupIOR(props,"extIOR","air");

if(intIOR<0||extIOR<0)

Log(EError,"Theinteriorandexteriorindicesof"

"refractionmustbepositive!");

m_eta=intIOR/extIOR;
m_invEta=1/m_eta;

m_specularReflectance=newConstantSpectrumTexture(

props.getSpectrum("specularReflectance",Spectrum(1.0f)));
m_specularTransmittance=newConstantSpectrumTexture(

props.getSpectrum("specularTransmittance",Spectrum(1.0f)));

SmoothDielectric(Stream*stream,InstanceManager*manager)

:BSDF(stream,manager){

m_eta=stream>readFloat();

m_specularReflectance=static_cast<Texture*>(manager>getInstance(stream));

m_specularTransmittance=static_cast<Texture*>(manager>getInstance(stream));

m_invEta=1/m_eta;

configure();
}

voidserialize(Stream*stream,InstanceManager*manager)const{

BSDF::serialize(stream,manager);

voidconfigure(){

/*Verifytheinputparametersandfixthemifnecessary*/

m_specularReflectance=ensureEnergyConservation(

m_specularReflectance,"specularReflectance",1.0f);

m_specularTransmittance=ensureEnergyConservation(

m_specularTransmittance,"specularTransmittance",1.0f);

m_components.clear();
m_components.push_back(EDeltaReflection|EFrontSide|EBackSide

|(m_specularReflectance>isConstant()?0:ESpatiallyVarying));
m_components.push_back(EDeltaTransmission|EFrontSide|EBackSide|ENonSymmetric

|(m_specularTransmittance>isConstant()?0:ESpatiallyVarying));

m_usesRayDifferentials=

m_specularReflectance>usesRayDifferentials()||

m_specularTransmittance>usesRayDifferentials();

BSDF::configure();

voidaddChild(conststd::string&name,ConfigurableObject*child){

if(child>getClass()>derivesFrom(MTS_CLASS(Texture))){

if(name=="specularReflectance")

m_specularReflectance=static_cast<Texture*>(child);

elseif(name=="specularTransmittance")

m_specularTransmittance=static_cast<Texture*>(child);

stream>writeFloat(m_eta);
manager>serialize(stream,m_specularReflectance.get());
manager>serialize(stream,m_specularTransmittance.get());

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

7/84

9/12/2016

mitApi

else

BSDF::addChild(name,child);
}else{

BSDF::addChild(name,child);
}

///Reflectioninlocalcoordinates
inlineVectorreflect(constVector&wi)const{

returnVector(wi.x,wi.y,wi.z);
}

///Refractioninlocalcoordinates
inlineVectorrefract(constVector&wi,FloatcosThetaT)const{

Floatscale=(cosThetaT<0?m_invEta:m_eta);

returnVector(scale*wi.x,scale*wi.y,cosThetaT);
}

Spectrumeval(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolsampleReflection=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0)&&measure==EDiscrete;

boolsampleTransmission=(bRec.typeMask&EDeltaTransmission)

&&(bRec.component==1||bRec.component==1)&&measure==EDiscrete;

FloatcosThetaT;
FloatF=fresnelDielectricExt(Frame::cosTheta(bRec.wi),cosThetaT,m_eta);

if(Frame::cosTheta(bRec.wi)*Frame::cosTheta(bRec.wo)>=0){

if(!sampleReflection||std::abs(dot(reflect(bRec.wi),bRec.wo)1)>DeltaEpsilon)

returnSpectrum(0.0f);

DeltaEpsilon)

returnm_specularReflectance>eval(bRec.its)*F;
}else{

if(!sampleTransmission||std::abs(dot(refract(bRec.wi,cosThetaT),bRec.wo)1)>

/*Radiancemustbescaledtoaccountforthesolidanglecompression
thatoccurswhencrossingtheinterface.*/
Floatfactor=(bRec.mode==ERadiance)

?(cosThetaT<0?m_invEta:m_eta):1.0f;

returnm_specularTransmittance>eval(bRec.its)*factor*factor*(1F);

Floatpdf(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolsampleReflection=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0)&&measure==EDiscrete;

boolsampleTransmission=(bRec.typeMask&EDeltaTransmission)

&&(bRec.component==1||bRec.component==1)&&measure==EDiscrete;

FloatcosThetaT;
FloatF=fresnelDielectricExt(Frame::cosTheta(bRec.wi),cosThetaT,m_eta);

if(Frame::cosTheta(bRec.wi)*Frame::cosTheta(bRec.wo)>=0){

if(!sampleReflection||std::abs(dot(reflect(bRec.wi),bRec.wo)1)>DeltaEpsilon)

return0.0f;

returnSpectrum(0.0f);

DeltaEpsilon)

returnsampleTransmission?F:1.0f;
}else{

if(!sampleTransmission||std::abs(dot(refract(bRec.wi,cosThetaT),bRec.wo)1)>

returnsampleReflection?1F:1.0f;

Spectrumsample(BSDFSamplingRecord&bRec,Float&pdf,constPoint2&sample)const{

boolsampleReflection=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0);

boolsampleTransmission=(bRec.typeMask&EDeltaTransmission)

&&(bRec.component==1||bRec.component==1);

FloatcosThetaT;
FloatF=fresnelDielectricExt(Frame::cosTheta(bRec.wi),cosThetaT,m_eta);

if(sampleTransmission&&sampleReflection){

if(sample.x<=F){

return0.0f;

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

8/84

9/12/2016

mitApi

bRec.sampledComponent=0;
bRec.sampledType=EDeltaReflection;
bRec.wo=reflect(bRec.wi);
bRec.eta=1.0f;
pdf=F;

returnm_specularReflectance>eval(bRec.its);
}else{

bRec.sampledComponent=1;

bRec.sampledType=EDeltaTransmission;

bRec.wo=refract(bRec.wi,cosThetaT);

bRec.eta=cosThetaT<0?m_eta:m_invEta;

pdf=1F;

returnm_specularTransmittance>eval(bRec.its)*(factor*factor);

}
}elseif(sampleReflection){

bRec.sampledComponent=0;

bRec.sampledType=EDeltaReflection;

bRec.wo=reflect(bRec.wi);

bRec.eta=1.0f;

pdf=1.0f;

returnm_specularReflectance>eval(bRec.its)*F;
}elseif(sampleTransmission){

bRec.sampledComponent=1;

bRec.sampledType=EDeltaTransmission;

bRec.wo=refract(bRec.wi,cosThetaT);

bRec.eta=cosThetaT<0?m_eta:m_invEta;

pdf=1.0f;

/*Radiancemustbescaledtoaccountforthesolidanglecompression
thatoccurswhencrossingtheinterface.*/
Floatfactor=(bRec.mode==ERadiance)

?(cosThetaT<0?m_invEta:m_eta):1.0f;

returnm_specularTransmittance>eval(bRec.its)*(factor*factor*(1F));

returnSpectrum(0.0f);

Spectrumsample(BSDFSamplingRecord&bRec,constPoint2&sample)const{

boolsampleReflection=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0);

boolsampleTransmission=(bRec.typeMask&EDeltaTransmission)

&&(bRec.component==1||bRec.component==1);

FloatcosThetaT;
FloatF=fresnelDielectricExt(Frame::cosTheta(bRec.wi),cosThetaT,m_eta);

if(sampleTransmission&&sampleReflection){

if(sample.x<=F){

bRec.sampledComponent=0;

bRec.sampledType=EDeltaReflection;

bRec.wo=reflect(bRec.wi);

bRec.eta=1.0f;

returnm_specularReflectance>eval(bRec.its);
}else{

bRec.sampledComponent=1;

bRec.sampledType=EDeltaTransmission;

bRec.wo=refract(bRec.wi,cosThetaT);

bRec.eta=cosThetaT<0?m_eta:m_invEta;

returnm_specularTransmittance>eval(bRec.its)*(factor*factor);

}
}elseif(sampleReflection){

bRec.sampledComponent=0;

bRec.sampledType=EDeltaReflection;

/*Radiancemustbescaledtoaccountforthesolidanglecompression
thatoccurswhencrossingtheinterface.*/
Floatfactor=(bRec.mode==ERadiance)

?(cosThetaT<0?m_invEta:m_eta):1.0f;

/*Radiancemustbescaledtoaccountforthesolidanglecompression
thatoccurswhencrossingtheinterface.*/
Floatfactor=(bRec.mode==ERadiance)

?(cosThetaT<0?m_invEta:m_eta):1.0f;

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

9/84

9/12/2016

mitApi

bRec.wo=reflect(bRec.wi);
bRec.eta=1.0f;

returnm_specularReflectance>eval(bRec.its)*F;
}elseif(sampleTransmission){

bRec.sampledComponent=1;

bRec.sampledType=EDeltaTransmission;

bRec.wo=refract(bRec.wi,cosThetaT);

bRec.eta=cosThetaT<0?m_eta:m_invEta;

/*Radiancemustbescaledtoaccountforthesolidanglecompression
thatoccurswhencrossingtheinterface.*/
Floatfactor=(bRec.mode==ERadiance)

?(cosThetaT<0?m_invEta:m_eta):1.0f;

returnm_specularTransmittance>eval(bRec.its)*(factor*factor*(1F));

returnSpectrum(0.0f);

FloatgetEta()const{

returnm_eta;
}

FloatgetRoughness(constIntersection&its,intcomponent)const{

return0.0f;
}

std::stringtoString()const{

std::ostringstreamoss;

oss<<"SmoothDielectric["<<endl

<<"id=\""<<getID()<<"\","<<endl

<<"eta="<<m_eta<<","<<endl

<<"specularReflectance="<<indent(m_specularReflectance>toString())<<","<<endl

<<"specularTransmittance="<<indent(m_specularTransmittance>toString())<<endl

<<"]";

returnoss.str();
}

Shader*createShader(Renderer*renderer)const;

MTS_DECLARE_CLASS()
private:

Floatm_eta,m_invEta;

ref<Texture>m_specularTransmittance;

ref<Texture>m_specularReflectance;
};
/*Fakeglassshaderitisreallyhopelesstovisualize
thismaterialintheVPLrenderer,solet'strytodoatleast
somethingthatsuggeststhepresenceofatransparentboundary*/
classSmoothDielectricShader:publicShader{
public:

SmoothDielectricShader(Renderer*renderer):

Shader(renderer,EBSDFShader){

m_flags=ETransparent;

FloatgetAlpha()const{

return0.3f;
}

voidgenerateCode(std::ostringstream&oss,

conststd::string&evalName,

conststd::vector<std::string>&depNames)const{

oss<<"vec3"<<evalName<<"(vec2uv,vec3wi,vec3wo){"<<endl

<<"if(cosTheta(wi)<0.0||cosTheta(wo)<0.0)"<<endl

<<"
returnvec3(0.0);"<<endl

<<"returnvec3(inv_pi*cosTheta(wo));"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"_diffuse(vec2uv,vec3wi,vec3wo){"<<endl

<<"return"<<evalName<<"(uv,wi,wo);"<<endl

<<"}"<<endl;
}

};

MTS_DECLARE_CLASS()

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

10/84

9/12/2016

mitApi

Shader*SmoothDielectric::createShader(Renderer*renderer)const{

returnnewSmoothDielectricShader(renderer);
}
MTS_IMPLEMENT_CLASS(SmoothDielectricShader,false,Shader)
MTS_IMPLEMENT_CLASS_S(SmoothDielectric,false,BSDF)
MTS_EXPORT_PLUGIN(SmoothDielectric,"SmoothdielectricBSDF");
MTS_NAMESPACE_END

https://raw.githubusercontent.com/mmanzi/gradientdomain
mitsuba/7f01a2c044440c774dd88afe05eea4acdc418f2c/src/bsdfs/conductor.cpp

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

11/84

9/12/2016

mitApi

#include<mitsuba/render/bsdf.h>
#include<mitsuba/core/fresolver.h>
#include<mitsuba/hw/basicshader.h>
#include<boost/algorithm/string.hpp>
#include"ior.h"
MTS_NAMESPACE_BEGIN
/*!\plugin{conductor}{Smoothconductor}
*\order{6}
*\icon{bsdf_conductor}
*\parameters{
*\parameter{material}{\String}{Nameofamaterialpreset,see
*\tblref{conductoriors}.\!\default{\texttt{Cu}/copper}}
*\parameter{eta,k}{\Spectrum}{Realandimaginarycomponentsofthematerial'sindexof
*refraction\default{basedonthevalueof\texttt{material}}}
*\parameter{extEta}{\Float\Or\String}{
*Realvaluedindexofrefractionofthesurroundingdielectric,
*oramaterialnameofadielectric\default{\code{air}}
*}
*\parameter{specular\showbreakReflectance}{\Spectrum\Or\Texture}{Optional
*factorthatcanbeusedtomodulatethespecularreflectioncomponent.Note
*thatforphysicalrealism,thisparametershouldneverbetouched.\default{1.0}}
*}
*\renderings{
*\rendering{Measuredcoppermaterial(thedefault),renderedusing30
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

12/84

9/12/2016

mitApi

*spectralsamplesbetween360and830$nm$}
*{bsdf_conductor_copper.jpg}
*\rendering{Measuredgoldmaterial(\lstref{conductorgold})}
*{bsdf_conductor_gold.jpg}
*}
*
*Thispluginimplementsaperfectlysmoothinterfacetoaconductingmaterial,
*suchasametal.Forasimilarmodelthatinsteaddescribesaroughsurface
*microstructure,takealookattheseparatelyavailable
*\pluginref{roughconductor}plugin.
*Incontrasttodielectricmaterials,conductorsdonottransmit
*anylight.Theirindexofrefractioniscomplexvaluedandtendstoundergo
*considerablechangesthroughoutthevisiblecolorspectrum.
*
*Tofacilitatethetedioustaskofspecifyingspectrallyvaryingindexof
*refractioninformation,Mitsubashipswithasetofmeasureddatafor
*severalmaterials,wherevisiblespectruminformationwaspublicly
*available\footnote{
*Theseindexofrefractionvaluesareidenticaltothedatadistributed
*withPBRT.TheyareoriginallyfromtheLuxpopdatabase
*(\url{www.luxpop.com})andarebasedondatabyPaliketal.
*\cite{Palik1998Handbook}andmeasurementsofatomicscatteringfactors
*madebytheCenterForXRayOptics(CXRO)atBerkeleyandthe
*LawrenceLivermoreNationalLaboratory(LLNL).
*}.
*
*Notethat\tblref{conductoriors}alsoincludesseveralpopularoptical
*coatings,whicharenotactuallyconductors.Thesematerialscanalso
*beusedwiththisplugin,thoughnotethatthepluginwillignoreany
*refractioncomponentthattheactualmaterialmighthavehad.
*Thereisalsoaspecialmaterialprofilenamed\code{none},whichdisables
*thecomputationofFresnelreflectancesandproducesanidealized
*100%reflectingmirror.
*
*Whenusingthisplugin,youshouldideallycompileMitsubawithsupportfor
*spectralrenderingtogetthemostaccurateresults.Whileitalsoworks
*inRGBmode,thecomputationswillbemoreapproximateinnature.
*Alsonotethatthismaterialisonesidedthatis,observedfromthe
*backside,itwillbecompletelyblack.Ifthisisundesirable,
*considerusingthe\pluginref{twosided}BRDFadapterplugin.\vspace{4mm}
*
*\begin{xml}[caption=Amaterialconfigurationforasmoothconductorwith
*measuredgolddata,label=lst:conductorgold]
*<shapetype="...">
*<bsdftype="conductor">
*<stringname="material"value="Au"/>
*</bsdf>
*<shape>
*\end{xml}
*\vspace{5mm}
*Itisalsopossibletoloadspectrallyvaryingindexofrefractiondatafrom
*twoexternalfilescontainingtherealandimaginarycomponents,
*respectively(see\secref{formatspectra}fordetailsonthefile
*format):
*\begin{xml}[caption=Renderingasmoothconductorwithcustomdata]
*<shapetype="...">
*<bsdftype="conductor">
*<spectrumname="eta"filename="conductorIOR.eta.spd"/>
*<spectrumname="k"filename="conductorIOR.k.spd"/>
*</bsdf>
*<shape>
*\end{xml}
*\vspace{1.5cm}
*\begin{table}[hb!]
*\centering
*\scriptsize
*\begin{tabular}{>{\ttfamily}llp{1mm}>{\ttfamily}ll}
*\toprule
*\rmfamily\textbf{Preset(s)}&\textbf{Description}&&
*\rmfamily\textbf{Preset(s)}&\textbf{Description}\\
*\cmidrule{12}\cmidrule{45}
*aC&Amorphouscarbon&&Na\_palik&Sodium\\
*Ag&Silver&&Nb,Nb\_palik&Niobium\\
*Al&Aluminium&&Ni\_palik&Nickel\\
*AlAs,AlAs\_palik&Cubicaluminiumarsenide&&Rh,Rh\_palik&Rhodium\\
*AlSb,AlSb\_palik&Cubicaluminiumantimonide&&Se,Se\_palik&Selenium\\
*Au&Gold&&SiC,SiC\_palik&Hexagonalsiliconcarbide\\
*Be,Be\_palik&Polycrystallineberyllium&&SnTe,SnTe\_palik&Tintelluride\\
*Cr&Chromium&&Ta,Ta\_palik&Tantalum\\
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

13/84

9/12/2016

mitApi

*CsI,CsI\_palik&Cubiccaesiumiodide&&Te,Te\_palik&Trigonaltellurium\\
*Cu,Cu\_palik&Copper&&ThF4,ThF4\_palik&Polycryst.thorium(IV)fluoride
\\
*Cu2O,Cu2O\_palik&Copper(I)oxide&&TiC,TiC\_palik&Polycrystallinetitaniumcarbide
\\
*CuO,CuO\_palik&Copper(II)oxide&&TiN,TiN\_palik&Titaniumnitride\\
*dC,dC\_palik&Cubicdiamond&&TiO2,TiO2\_palik&Tetragonaltitan.dioxide\\
*Hg,Hg\_palik&Mercury&&VC,VC\_palik&Vanadiumcarbide\\
*HgTe,HgTe\_palik&Mercurytelluride&&V\_palik&Vanadium\\
*Ir,Ir\_palik&Iridium&&VN,VN\_palik&Vanadiumnitride\\
*K,K\_palik&Polycrystallinepotassium&&W&Tungsten\\
*Li,Li\_palik&Lithium&&\\
*MgO,MgO\_palik&Magnesiumoxide&&\\
*Mo,Mo\_palik&Molybdenum&&none&Nomat.profile($\to$100%reflectingmirror)\\
*\bottomrule
*\end{tabular}
*\caption{
*\label{tbl:conductoriors}
*Thistablelistsallsupportedmaterialsthatcanbepassedintothe
*\pluginref{conductor}and\pluginref{roughconductor}plugins.Notethat
*someofthemarenotactuallyconductorsthisisnotaproblem,
*theycanbeusedregardless(thoughonlythereflectioncomponentand
*notransmissionwillbesimulated).Inmostcases,thereare
*multipleentriesforeachmaterial,whichrepresentmeasurementsby
*differentauthors.
*}
*\end{table}
*/
classSmoothConductor:publicBSDF{
public:

SmoothConductor(constProperties&props):BSDF(props){

ref<FileResolver>fResolver=Thread::getThread()>getFileResolver();

m_specularReflectance=newConstantSpectrumTexture(

props.getSpectrum("specularReflectance",Spectrum(1.0f)));

std::stringmaterialName=props.getString("material","Cu");

SpectrumintEta,intK;
if(boost::to_lower_copy(materialName)=="none"){

intEta=Spectrum(0.0f);

intK=Spectrum(1.0f);
}else{

intEta.fromContinuousSpectrum(InterpolatedSpectrum(

fResolver>resolve("data/ior/"+materialName+".eta.spd")));

intK.fromContinuousSpectrum(InterpolatedSpectrum(

fResolver>resolve("data/ior/"+materialName+".k.spd")));
}

FloatextEta=lookupIOR(props,"extEta","air");

m_eta=props.getSpectrum("eta",intEta)/extEta;
m_k=props.getSpectrum("k",intK)/extEta;

SmoothConductor(Stream*stream,InstanceManager*manager)

:BSDF(stream,manager){

m_specularReflectance=static_cast<Texture*>(manager>getInstance(stream));

m_eta=Spectrum(stream);

m_k=Spectrum(stream);

voidconfigure(){

/*Verifytheinputparametersandfixthemifnecessary*/

m_specularReflectance=ensureEnergyConservation(

m_specularReflectance,"specularReflectance",1.0f);

m_usesRayDifferentials=

m_specularReflectance>usesRayDifferentials();

m_components.clear();
m_components.push_back(EDeltaReflection|EFrontSide

|(m_specularReflectance>isConstant()?0:ESpatiallyVarying));

BSDF::configure();

voidserialize(Stream*stream,InstanceManager*manager)const{

configure();

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

14/84

9/12/2016

mitApi

BSDF::serialize(stream,manager);
manager>serialize(stream,m_specularReflectance.get());
m_eta.serialize(stream);
m_k.serialize(stream);

voidaddChild(conststd::string&name,ConfigurableObject*child){

if(child>getClass()>derivesFrom(MTS_CLASS(Texture))&&name=="specularReflectance"){

m_specularReflectance=static_cast<Texture*>(child);

m_usesRayDifferentials|=m_specularReflectance>usesRayDifferentials();

}else{

BSDF::addChild(name,child);

}
}

///Reflectioninlocalcoordinates
inlineVectorreflect(constVector&wi)const{

returnVector(wi.x,wi.y,wi.z);
}

Spectrumeval(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolsampleReflection=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0);

/*Verifythattheprovideddirectionpairmatchesanideal
specularreflection;toleratesomeroundofferrors*/
if(!sampleReflection||measure!=EDiscrete||

Frame::cosTheta(bRec.wi)<=0||

Frame::cosTheta(bRec.wo)<=0||

std::abs(dot(reflect(bRec.wi),bRec.wo)1)>DeltaEpsilon)

returnSpectrum(0.0f);

returnm_specularReflectance>eval(bRec.its)*

fresnelConductorExact(Frame::cosTheta(bRec.wi),m_eta,m_k);

Floatpdf(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolsampleReflection=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0);

/*Verifythattheprovideddirectionpairmatchesanideal
specularreflection;toleratesomeroundofferrors*/
if(!sampleReflection||measure!=EDiscrete||

Frame::cosTheta(bRec.wi)<=0||

Frame::cosTheta(bRec.wo)<=0||

std::abs(dot(reflect(bRec.wi),bRec.wo)1)>DeltaEpsilon)

return0.0f;

return1.0f;

Spectrumsample(BSDFSamplingRecord&bRec,constPoint2&sample)const{

boolsampleReflection=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0);

if(!sampleReflection||Frame::cosTheta(bRec.wi)<=0)

returnSpectrum(0.0f);

bRec.sampledComponent=0;
bRec.sampledType=EDeltaReflection;
bRec.wo=reflect(bRec.wi);
bRec.eta=1.0f;

returnm_specularReflectance>eval(bRec.its)*

fresnelConductorExact(Frame::cosTheta(bRec.wi),m_eta,m_k);

Spectrumsample(BSDFSamplingRecord&bRec,Float&pdf,constPoint2&sample)const{

boolsampleReflection=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0);

if(!sampleReflection||Frame::cosTheta(bRec.wi)<=0)

returnSpectrum(0.0f);

bRec.sampledComponent=0;
bRec.sampledType=EDeltaReflection;
bRec.wo=reflect(bRec.wi);
bRec.eta=1.0f;
pdf=1;

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

15/84

9/12/2016

mitApi

returnm_specularReflectance>eval(bRec.its)*

fresnelConductorExact(Frame::cosTheta(bRec.wi),m_eta,m_k);

FloatgetRoughness(constIntersection&its,intcomponent)const{

return0.0f;
}

std::stringtoString()const{

std::ostringstreamoss;

oss<<"SmoothConductor["<<endl

<<"id=\""<<getID()<<"\","<<endl

<<"eta="<<m_eta.toString()<<","<<endl

<<"k="<<m_k.toString()<<","<<endl

<<"specularReflectance="<<indent(m_specularReflectance>toString())<<endl

<<"]";

returnoss.str();
}

Shader*createShader(Renderer*renderer)const;

MTS_DECLARE_CLASS()
private:

ref<Texture>m_specularReflectance;

Spectrumm_eta;

Spectrumm_k;
};
/*Smoothconductorshaderitisreallyhopelesstovisualize
thismaterialintheVPLrenderer,solet'strytodoatleast
somethingthatsuggeststhepresenceofaspecularlyreflecting
conductor.
Thecodebelowisanisotropicversionoftheshaderin
roughconductor.cpp,with\alphafixedto0.4f
*/
classSmoothConductorShader:publicShader{
public:

SmoothConductorShader(Renderer*renderer,constTexture*specularReflectance,

constSpectrum&eta,constSpectrum&k):Shader(renderer,EBSDFShader),

m_specularReflectance(specularReflectance){

m_specularReflectanceShader=renderer>registerShaderForResource(m_specularReflectance.get());

/*Computethereflectanceatperpendicularincidence*/
m_R0=fresnelConductorExact(1.0f,eta,k);

m_alpha=0.4f;

boolisComplete()const{

returnm_specularReflectanceShader.get()!=NULL;
}

voidputDependencies(std::vector<Shader*>&deps){

deps.push_back(m_specularReflectanceShader.get());
}

voidcleanup(Renderer*renderer){

renderer>unregisterShaderForResource(m_specularReflectance.get());
}

voidresolve(constGPUProgram*program,conststd::string&evalName,std::vector<int>&parameterIDs)const

voidbind(GPUProgram*program,conststd::vector<int>&parameterIDs,int&textureUnitOffset)const{

program>setParameter(parameterIDs[0],m_R0);
}

voidgenerateCode(std::ostringstream&oss,

conststd::string&evalName,

conststd::vector<std::string>&depNames)const{

oss<<"uniformvec3"<<evalName<<"_R0;"<<endl

<<endl

<<"float"<<evalName<<"_D(vec3m,floatalpha){"<<endl

<<"alpha=2/(alpha*alpha)2;"<<endl

<<"return(alpha+2)*0.15915*pow(cosTheta(m),alpha);"<<endl

<<"}"<<endl

<<endl

parameterIDs.push_back(program>getParameterID(evalName+"_R0",false));

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

16/84

9/12/2016

mitApi

<<"float"<<evalName<<"_G(vec3m,vec3wi,vec3wo){"<<endl

<<"if((dot(wi,m)*cosTheta(wi))<=0||"<<endl

<<"(dot(wo,m)*cosTheta(wo))<=0)"<<endl

<<"return0.0;"<<endl

<<"floatnDotM=cosTheta(m);"<<endl

<<"returnmin(1.0,min("<<endl

<<"abs(2*nDotM*cosTheta(wo)/dot(wo,m)),"<<endl

<<"abs(2*nDotM*cosTheta(wi)/dot(wi,m))));"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"_schlick(floatct){"<<endl

<<"floatctSqr=ct*ct,ct5=ctSqr*ctSqr*ct;"<<endl

<<"return"<<evalName<<"_R0+(vec3(1.0)"<<evalName<<"_R0)*ct5;"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"(vec2uv,vec3wi,vec3wo){"<<endl

<<"if(cosTheta(wi)<=0||cosTheta(wo)<=0)"<<endl

<<"
returnvec3(0.0);"<<endl

<<"vec3H=normalize(wi+wo);"<<endl

<<"vec3reflectance="<<depNames[0]<<"(uv);"<<endl

<<"floatD="<<evalName<<"_D(H,"<<m_alpha<<")"<<";"<<endl

<<"floatG="<<evalName<<"_G(H,wi,wo);"<<endl

<<"vec3F="<<evalName<<"_schlick(1dot(wi,H));"<<endl

<<"returnreflectance*F*(D*G/(4*cosTheta(wi)));"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"_diffuse(vec2uv,vec3wi,vec3wo){"<<endl

<<"if(cosTheta(wi)<0.0||cosTheta(wo)<0.0)"<<endl

<<"
returnvec3(0.0);"<<endl

<<"return"<<evalName<<"_R0*inv_pi*inv_pi*cosTheta(wo);"<<endl

<<"}"<<endl;

MTS_DECLARE_CLASS()
private:

ref<constTexture>m_specularReflectance;

ref<Shader>m_specularReflectanceShader;

Spectrumm_R0;

Floatm_alpha;
};
Shader*SmoothConductor::createShader(Renderer*renderer)const{

returnnewSmoothConductorShader(renderer,

m_specularReflectance.get(),m_eta,m_k);
}
MTS_IMPLEMENT_CLASS(SmoothConductorShader,false,Shader)
MTS_IMPLEMENT_CLASS_S(SmoothConductor,false,BSDF)
MTS_EXPORT_PLUGIN(SmoothConductor,"Smoothconductor");
MTS_NAMESPACE_END

https://raw.githubusercontent.com/mmanzi/gradientdomain
mitsuba/7f01a2c044440c774dd88afe05eea4acdc418f2c/src/bsdfs/coating.cpp

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

17/84

9/12/2016

mitApi

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

18/84

9/12/2016

mitApi

#include<mitsuba/render/bsdf.h>
#include<mitsuba/hw/basicshader.h>
#include"ior.h"
MTS_NAMESPACE_BEGIN
/*!\plugin{coating}{Smoothdielectriccoating}
*\order{10}
*\icon{bsdf_coating}
*
*\parameters{
*\parameter{intIOR}{\Float\Or\String}{Interiorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{bk7}/1.5046}}
*\parameter{extIOR}{\Float\Or\String}{Exteriorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{air}/1.000277}}
*\parameter{thickness}{\Float}{Denotesthethicknessofthelayer(to
*modelabsorptionshouldbespecifiedininverseunitsof\code{sigmaA})\default{1}}
*\parameter{sigmaA}{\Spectrum\Or\Texture}{Theabsorptioncoefficientofthe
*coatinglayer.\default{0,i.e.thereisnoabsorption}}
*\parameter{specular\showbreakReflectance}{\Spectrum\Or\Texture}{Optional
*factorthatcanbeusedtomodulatethespecularreflectioncomponent.Note
*thatforphysicalrealism,thisparametershouldneverbetouched.\default{1.0}}
*\parameter{\Unnamed}{\BSDF}{AnestedBSDFmodelthatshouldbecoated.}
*}
*
*\renderings{
*\rendering{Roughcopper}
*{bsdf_coating_uncoated}
*\rendering{Thesamematerialcoatedwithasinglelayerof
*clearvarnish(see\lstref{coatingroughcopper})}
*{bsdf_coating_roughconductor}
*}
*
*Thispluginimplementsasmoothdielectriccoating(e.g.alayerofvarnish)
*inthestyleofthepaper``ArbitrarilyLayeredMicroFacetSurfaces''by
*WeidlichandWilkie\cite{Weidlich2007Arbitrarily}.AnyBSDFinMitsuba
*canbecoatedusingthisplugin,andmultiplecoatinglayerscaneven
*beappliedinsequence.Thisallowsdesigninginterestingcustommaterials
*likecarpaintorglazedmetalfoil.Thecoatinglayercanoptionallybe
*tinted(i.e.filledwithanabsorbingmedium),inwhichcasethismodelalso
*accountsforthedirectionallydependentabsorptionwithinthelayer.
*
*Notethattheplugindiscardsilluminationthatundergoesinternal
*reflectionwithinthecoating.Thiscanleadtoanoticeableenergy
*lossformaterialsthatreflectmuchoftheirenergynearorbelowthecritical
*angle(i.e.diffuseorveryroughmaterials).
*Therefore,usersarediscouragedtousethisplugintocoatsmooth
*diffusematerials,sincethereisaseparatelyavailableplugin
*named\pluginref{plastic},whichcoversthesamecaseanddoesnot
*sufferfromenergyloss.\newpage
*
*\renderings{
*\smallrendering{$\code{thickness}=0$}{bsdf_coating_0}
*\smallrendering{$\code{thickness}=1$}{bsdf_coating_1}
*\smallrendering{$\code{thickness}=5$}{bsdf_coating_5}
*\smallrendering{$\code{thickness}=15$}{bsdf_coating_15}
*\caption{Theeffectofthelayerthicknessparameteron
*atintedcoating($\code{sigmaT}=(0.1,0.2,0.5)$)}
*}
*
*\vspace{4mm}
*
*\begin{xml}[caption=Roughcoppercoatedwithatransparentlayerof
*varnish,label=lst:coatingroughcopper]
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

19/84

9/12/2016

mitApi

*<bsdftype="coating">
*<floatname="intIOR"value="1.7"/>
*
*<bsdftype="roughconductor">
*<stringname="material"value="Cu"/>
*<floatname="alpha"value="0.1"/>
*</bsdf>
*</bsdf>
*\end{xml}
*
*\renderings{
*\rendering{Coatedroughcopperwithabumpmapappliedontop}{bsdf_coating_coatedbump}
*\rendering{Bumpmappedroughcopperwithacoatingontop}{bsdf_coating_bumpcoating}
*\caption{Someinterestingmaterialscanbecreatedsimplybyapplying
*Mitsuba'smaterialmodifiersindifferentorders.}
*}
*
*\subsubsection*{Technicaldetails}
*Evaluatingtheinternalcomponentofthismodelentailsrefractingthe
*incidentandexitantraysthroughthedielectricinterface,followedby
*queryingthenestedmaterialwiththismodifieddirectionpair.Theresult
*isattenuatedbythetwoFresneltransmittancesandtheabsorption,if
*any.
*/
classSmoothCoating:publicBSDF{
public:

SmoothCoating(constProperties&props)

:BSDF(props){

/*Specifiestheinternalindexofrefractionattheinterface*/

FloatintIOR=lookupIOR(props,"intIOR","bk7");

/*Specifiestheexternalindexofrefractionattheinterface*/
FloatextIOR=lookupIOR(props,"extIOR","air");

if(intIOR<0||extIOR<0||intIOR==extIOR)

Log(EError,"Theinteriorandexteriorindicesof"

"refractionmustbepositiveanddiffer!");

m_eta=intIOR/extIOR;
m_invEta=1/m_eta;

/*Specifiesthelayer'sthicknessusingtheinverseunitsofsigmaA*/
m_thickness=props.getFloat("thickness",1);

/*Specifiestheabsorptionwithinthelayer*/
m_sigmaA=newConstantSpectrumTexture(

props.getSpectrum("sigmaA",Spectrum(0.0f)));

/*Specifiesamultiplierforthespecularreflectancecomponent*/
m_specularReflectance=newConstantSpectrumTexture(

props.getSpectrum("specularReflectance",Spectrum(1.0f)));

SmoothCoating(Stream*stream,InstanceManager*manager)

:BSDF(stream,manager){

m_eta=stream>readFloat();

m_thickness=stream>readFloat();

m_nested=static_cast<BSDF*>(manager>getInstance(stream));

m_sigmaA=static_cast<Texture*>(manager>getInstance(stream));

m_specularReflectance=static_cast<Texture*>(manager>getInstance(stream));

m_invEta=1/m_eta;

configure();
}

voidserialize(Stream*stream,InstanceManager*manager)const{

BSDF::serialize(stream,manager);

voidconfigure(){

if(!m_nested)

Log(EError,"AchildBSDFinstanceisrequired");

stream>writeFloat(m_eta);
stream>writeFloat(m_thickness);
manager>serialize(stream,m_nested.get());
manager>serialize(stream,m_sigmaA.get());
manager>serialize(stream,m_specularReflectance.get());

unsignedintextraFlags=0;
if(!m_sigmaA>isConstant())

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

20/84

9/12/2016

mitApi

extraFlags|=ESpatiallyVarying;

m_components.clear();
for(inti=0;i<m_nested>getComponentCount();++i)

m_components.push_back(m_nested>getType(i)|extraFlags);

m_components.push_back(EDeltaReflection|EFrontSide|EBackSide

|(m_specularReflectance>isConstant()?0:ESpatiallyVarying));

m_usesRayDifferentials=m_nested>usesRayDifferentials()

||m_sigmaA>usesRayDifferentials()

||m_specularReflectance>usesRayDifferentials();

/*Computeweightsthatfurthersteersamplestowards
thespecularornestedcomponents*/
FloatavgAbsorption=(m_sigmaA>getAverage()

*(2*m_thickness)).exp().average();

m_specularSamplingWeight=1.0f/(avgAbsorption+1.0f);

/*Verifytheinputparametersandfixthemifnecessary*/
m_specularReflectance=ensureEnergyConservation(

m_specularReflectance,"specularReflectance",1.0f);

BSDF::configure();

voidaddChild(conststd::string&name,ConfigurableObject*child){

if(child>getClass()>derivesFrom(MTS_CLASS(BSDF))){

if(m_nested!=NULL)

Log(EError,"OnlyasinglenestedBRDFcanbeadded!");

m_nested=static_cast<BSDF*>(child);

}elseif(child>getClass()>derivesFrom(MTS_CLASS(Texture))&&name=="sigmaA"){

m_sigmaA=static_cast<Texture*>(child);

}else{

BSDF::addChild(name,child);

}
}

///Reflectioninlocalcoordinates
inlineVectorreflect(constVector&wi)const{

returnVector(wi.x,wi.y,wi.z);
}

///Refractintothematerial,preservesignofdirection
inlineVectorrefractIn(constVector&wi,Float&R)const{

FloatcosThetaT;

R=fresnelDielectricExt(std::abs(Frame::cosTheta(wi)),cosThetaT,m_eta);

returnVector(m_invEta*wi.x,m_invEta*wi.y,math::signum(Frame::cosTheta(wi))*cosThetaT);
}

///Refractoutofthematerial,preservesignofdirection
inlineVectorrefractOut(constVector&wi,Float&R)const{

FloatcosThetaT;

R=fresnelDielectricExt(std::abs(Frame::cosTheta(wi)),cosThetaT,m_invEta);

returnVector(m_eta*wi.x,m_eta*wi.y,math::signum(Frame::cosTheta(wi))*cosThetaT);
}

Spectrumeval(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolsampleSpecular=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==(int)m_components.size()1);

boolsampleNested=(bRec.typeMask&m_nested>getType()&BSDF::EAll)

&&(bRec.component==1||bRec.component<(int)m_components.size()1);

if(measure==EDiscrete&&sampleSpecular&&

std::abs(dot(reflect(bRec.wi),bRec.wo)1)<DeltaEpsilon){

returnm_specularReflectance>eval(bRec.its)*

fresnelDielectricExt(std::abs(Frame::cosTheta(bRec.wi)),m_eta);
}elseif(sampleNested){

FloatR12,R21;

BSDFSamplingRecordbRecInt(bRec);

bRecInt.wi=refractIn(bRec.wi,R12);

bRecInt.wo=refractIn(bRec.wo,R21);

if(R12==1||R21==1)/*Totalinternalreflection*/

returnSpectrum(0.0f);

Spectrumresult=m_nested>eval(bRecInt,measure)

*(1R12)*(1R21);

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

21/84

9/12/2016

mitApi

SpectrumsigmaA=m_sigmaA>eval(bRec.its)*m_thickness;
if(!sigmaA.isZero())

result*=(sigmaA*

(1/std::abs(Frame::cosTheta(bRecInt.wi))+

1/std::abs(Frame::cosTheta(bRecInt.wo)))).exp();

/*Solidanglecompression&irradianceconversionfactors*/
if(measure==ESolidAngle)

result*=m_invEta*m_invEta*

Frame::cosTheta(bRec.wo)/Frame::cosTheta(bRecInt.wo);

returnresult;

returnSpectrum(0.0f);

Floatpdf(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolsampleSpecular=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==(int)m_components.size()1);

boolsampleNested=(bRec.typeMask&m_nested>getType()&BSDF::EAll)

&&(bRec.component==1||bRec.component<(int)m_components.size()1);

FloatR12;
VectorwiPrime=refractIn(bRec.wi,R12);

/*Reallocatesamples*/
FloatprobSpecular=(R12*m_specularSamplingWeight)/

(R12*m_specularSamplingWeight+

(1R12)*(1m_specularSamplingWeight));

if(measure==EDiscrete&&sampleSpecular&&

std::abs(dot(reflect(bRec.wi),bRec.wo)1)<DeltaEpsilon){

returnsampleNested?probSpecular:1.0f;
}elseif(sampleNested){

FloatR21;

BSDFSamplingRecordbRecInt(bRec);

bRecInt.wi=wiPrime;

bRecInt.wo=refractIn(bRec.wo,R21);

if(R12==1||R21==1)/*Totalinternalreflection*/

return0.0f;

Floatpdf=m_nested>pdf(bRecInt,measure);

if(measure==ESolidAngle)

pdf*=m_invEta*m_invEta*Frame::cosTheta(bRec.wo)
/Frame::cosTheta(bRecInt.wo);

returnsampleSpecular?(pdf*(1probSpecular)):pdf;
}else{

return0.0f;
}

Spectrumsample(BSDFSamplingRecord&bRec,Float&pdf,constPoint2&_sample)const{

boolsampleSpecular=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==(int)m_components.size()1);

boolsampleNested=(bRec.typeMask&m_nested>getType()&BSDF::EAll)

&&(bRec.component==1||bRec.component<(int)m_components.size()1);

if((!sampleSpecular&&!sampleNested))

returnSpectrum(0.0f);

FloatR12;
VectorwiPrime=refractIn(bRec.wi,R12);

/*Reallocatesamples*/
FloatprobSpecular=(R12*m_specularSamplingWeight)/

(R12*m_specularSamplingWeight+

(1R12)*(1m_specularSamplingWeight));

boolchoseSpecular=sampleSpecular;

Point2sample(_sample);
if(sampleSpecular&&sampleNested){

if(sample.x<probSpecular){

sample.x/=probSpecular;

}else{

sample.x=(sample.xprobSpecular)/(1probSpecular);

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

22/84

9/12/2016

mitApi

choseSpecular=false;

if(choseSpecular){

bRec.sampledComponent=(int)m_components.size()1;

bRec.sampledType=EDeltaReflection;

bRec.wo=reflect(bRec.wi);

bRec.eta=1.0f;

pdf=sampleNested?probSpecular:1.0f;

returnm_specularReflectance>eval(bRec.its)*(R12/pdf);
}else{

if(R12==1.0f)/*Totalinternalreflection*/

returnSpectrum(0.0f);

VectorwiBackup=bRec.wi;
bRec.wi=wiPrime;
FloattemporaryPdf(0);
Spectrumresult=m_nested>sample(bRec,temporaryPdf,sample);
bRec.wi=wiBackup;
if(temporaryPdf==(Float)0)

returnSpectrum(0.0f);

VectorwoPrime=bRec.wo;

SpectrumsigmaA=m_sigmaA>eval(bRec.its)*m_thickness;
if(!sigmaA.isZero())

result*=(sigmaA*

(1/std::abs(Frame::cosTheta(wiPrime))+

1/std::abs(Frame::cosTheta(woPrime)))).exp();

FloatR21;
bRec.wo=refractOut(woPrime,R21);
if(R21==1.0f)/*Totalinternalreflection*/

returnSpectrum(0.0f);

if(sampleSpecular){

temporaryPdf*=1.0fprobSpecular;

result/=1.0fprobSpecular;
}

result*=(1R12)*(1R21);

/*Solidanglecompression&irradianceconversionfactors*/

if(BSDF::getMeasure(bRec.sampledType)==ESolidAngle)

temporaryPdf*=m_invEta*m_invEta*Frame::cosTheta(bRec.wo)/
Frame::cosTheta(woPrime);

pdf=temporaryPdf;
returnresult;

Spectrumsample(BSDFSamplingRecord&bRec,constPoint2&sample)const{

Floatpdf;

returnSmoothCoating::sample(bRec,pdf,sample);
}

FloatgetRoughness(constIntersection&its,intcomponent)const{

returncomponent<(int)m_components.size()1

?m_nested>getRoughness(its,component):(Float)0;
}

std::stringtoString()const{

std::ostringstreamoss;

oss<<"SmoothCoating["<<endl

<<"id=\""<<getID()<<"\","<<endl

<<"eta="<<m_eta<<","<<endl

<<"specularSamplingWeight="<<m_specularSamplingWeight<<","<<endl

<<"sigmaA="<<indent(m_sigmaA>toString())<<","<<endl

<<"specularReflectance="<<indent(m_specularReflectance>toString())<<","<<endl

<<"thickness="<<m_thickness<<","<<endl

<<"nested="<<indent(m_nested.toString())<<endl

<<"]";

returnoss.str();
}

Shader*createShader(Renderer*renderer)const;

MTS_DECLARE_CLASS()

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

23/84

9/12/2016

mitApi

protected:

Floatm_specularSamplingWeight;

Floatm_eta,m_invEta;

ref<Texture>m_sigmaA;

ref<Texture>m_specularReflectance;

ref<BSDF>m_nested;

Floatm_thickness;
};
//================Hardwareshaderimplementation================
/**
*SimpleGLSLversionusesSchlick'sapproximationandapproximatesthe
*ideallyspecularreflectionwithasomewhatsmoothedoutreflectionlobe
*/
classSmoothCoatingShader:publicShader{
public:

SmoothCoatingShader(Renderer*renderer,Floateta,constBSDF*nested,

constTexture*sigmaA):Shader(renderer,EBSDFShader),

m_nested(nested),m_sigmaA(sigmaA),m_eta(eta){

m_nestedShader=renderer>registerShaderForResource(m_nested.get());

m_sigmaAShader=renderer>registerShaderForResource(m_sigmaA.get());

m_R0=fresnelDielectricExt(1.0f,eta);

boolisComplete()const{

returnm_nestedShader.get()!=NULL

&&m_sigmaAShader.get()!=NULL;
}

voidcleanup(Renderer*renderer){

renderer>unregisterShaderForResource(m_nested.get());

renderer>unregisterShaderForResource(m_sigmaA.get());
}

voidputDependencies(std::vector<Shader*>&deps){

deps.push_back(m_nestedShader.get());

deps.push_back(m_sigmaAShader.get());
}

voidresolve(constGPUProgram*program,conststd::string&evalName,std::vector<int>&parameterIDs)const

voidbind(GPUProgram*program,conststd::vector<int>&parameterIDs,int&textureUnitOffset)const{

program>setParameter(parameterIDs[0],m_R0);

program>setParameter(parameterIDs[1],m_eta);

program>setParameter(parameterIDs[2],0.4f);
}

endl

voidgenerateCode(std::ostringstream&oss,

conststd::string&evalName,

conststd::vector<std::string>&depNames)const{

oss<<"uniformfloat"<<evalName<<"_R0;"<<endl

<<"uniformfloat"<<evalName<<"_eta;"<<endl

<<"uniformfloat"<<evalName<<"_alpha;"<<endl

<<endl

<<"float"<<evalName<<"_schlick(floatct){"<<endl

<<"floatctSqr=ct*ct,ct5=ctSqr*ctSqr*ct;"<<endl

<<"return"<<evalName<<"_R0+(1.0"<<evalName<<"_R0)*ct5;"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"_refract(vec3wi,outfloatT){"<<endl

<<"floatcosThetaI=cosTheta(wi);"<<endl

<<"boolentering=cosThetaI>0.0;"<<endl

<<"floatinvEta=1.0/"<<evalName<<"_eta;"<<endl

<<"floatsinThetaTSqr=invEta*invEta*sinTheta2(wi);"<<endl

<<"if(sinThetaTSqr>=1.0){"<<endl

<<"T=0.0;/*Totalinternalreflection*/"<<endl

<<"returnvec3(0.0);"<<endl

<<"}else{"<<endl

<<"floatcosThetaT=sqrt(1.0sinThetaTSqr);"<<endl

<<"T=1.0"<<evalName<<"_schlick(1.0abs(cosThetaI));"<<endl

<<"returnvec3(invEta*wi.x,invEta*wi.y,entering?cosThetaT:cosThetaT);"<<

parameterIDs.push_back(program>getParameterID(evalName+"_R0",false));
parameterIDs.push_back(program>getParameterID(evalName+"_eta",false));
parameterIDs.push_back(program>getParameterID(evalName+"_alpha",false));

<<"}"<<endl
<<"}"<<endl

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

24/84

9/12/2016

mitApi

<<endl
<<"float"<<evalName<<"_D(vec3m){"<<endl
<<"floatct=cosTheta(m);"<<endl
<<"if(cosTheta(m)<=0.0)"<<endl
<<"return0.0;"<<endl
<<"floatex=tanTheta(m)/"<<evalName<<"_alpha;"<<endl
<<"returnexp((ex*ex))/(pi*"<<evalName<<"_alpha"<<endl
<<"*"<<evalName<<"_alpha*pow(cosTheta(m),4.0));"<<endl
<<"}"<<endl
<<endl
<<"float"<<evalName<<"_G(vec3m,vec3wi,vec3wo){"<<endl
<<"if((dot(wi,m)*cosTheta(wi))<=0||"<<endl
<<"(dot(wo,m)*cosTheta(wo))<=0)"<<endl
<<"return0.0;"<<endl
<<"floatnDotM=cosTheta(m);"<<endl
<<"returnmin(1.0,min("<<endl
<<"abs(2*nDotM*cosTheta(wo)/dot(wo,m)),"<<endl
<<"abs(2*nDotM*cosTheta(wi)/dot(wi,m))));"<<endl
<<"}"<<endl
<<endl
<<"vec3"<<evalName<<"(vec2uv,vec3wi,vec3wo){"<<endl
<<"floatT12,T21;"<<endl
<<"vec3wiPrime="<<evalName<<"_refract(wi,T12);"<<endl
<<"vec3woPrime="<<evalName<<"_refract(wo,T21);"<<endl
<<"vec3nested="<<depNames[0]<<"(uv,wiPrime,woPrime);"<<endl
<<"vec3sigmaA="<<depNames[1]<<"(uv);"<<endl
<<"vec3result=nested*"<<evalName<<"_eta*"<<evalName<<"_eta"<<endl
<<"*T12*T21*(cosTheta(wi)*cosTheta(wo))/"<<endl
<<"(cosTheta(wiPrime)*cosTheta(woPrime));"<<endl
<<"if(sigmaA!=vec3(0.0))"<<endl
<<"result*=exp(sigmaA*(1/abs(cosTheta(wiPrime))+"<<endl
<<"1/abs(cosTheta(woPrime))));"<<endl
<<"if(cosTheta(wi)*cosTheta(wo)>0){"<<endl
<<"vec3H=normalize(wi+wo);"<<endl
<<"if(H.z<0)H=H;"<<endl
<<"floatD="<<evalName<<"_D(H)"<<";"<<endl
<<"floatG="<<evalName<<"_G(H,wi,wo);"<<endl
<<"floatF="<<evalName<<"_schlick(1abs(dot(wi,H)));"<<endl
<<"result+=vec3(abs(F*D*G)/abs(4*cosTheta(wi)));"<<endl
<<"}"<<endl
<<"returnresult;"<<endl
<<"}"<<endl
<<endl
<<"vec3"<<evalName<<"_diffuse(vec2uv,vec3wi,vec3wo){"<<endl
<<"return"<<depNames[0]<<"_diffuse(uv,wi,wo);"<<endl
<<"}"<<endl;

MTS_DECLARE_CLASS()
private:

ref<constBSDF>m_nested;

ref<Shader>m_nestedShader;

ref<constTexture>m_sigmaA;

ref<Shader>m_sigmaAShader;

Floatm_R0,m_eta;
};
Shader*SmoothCoating::createShader(Renderer*renderer)const{

returnnewSmoothCoatingShader(renderer,m_eta,

m_nested.get(),m_sigmaA.get());
}
MTS_IMPLEMENT_CLASS(SmoothCoatingShader,false,Shader)
MTS_IMPLEMENT_CLASS_S(SmoothCoating,false,BSDF)
MTS_EXPORT_PLUGIN(SmoothCoating,"Smoothdielectriccoating");
MTS_NAMESPACE_END

https://raw.githubusercontent.com/mmanzi/gradientdomain
mitsuba/7f01a2c044440c774dd88afe05eea4acdc418f2c/src/bsdfs/plastic.cpp

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

25/84

9/12/2016

mitApi

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

26/84

9/12/2016

mitApi

#include<mitsuba/render/bsdf.h>
#include<mitsuba/hw/basicshader.h>
#include<mitsuba/core/warp.h>
#include"ior.h"
MTS_NAMESPACE_BEGIN
/*!\plugin{plastic}{Smoothplasticmaterial}
*\order{8}
*\icon{bsdf_plastic}
*\parameters{
*\parameter{intIOR}{\Float\Or\String}{Interiorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{polypropylene}/1.49}}
*\parameter{extIOR}{\Float\Or\String}{Exteriorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{air}/1.000277}}
*\parameter{specular\showbreakReflectance}{\Spectrum\Or\Texture}{Optional
*factorthatcanbeusedtomodulatethespecularreflectioncomponent.Notethat
*forphysicalrealism,thisparametershouldneverbetouched.\default{1.0}}
*\parameter{diffuse\showbreakReflectance}{\Spectrum\Or\Texture}{Optional
*factorusedtomodulatethediffusereflectioncomponent\default{0.5}}
*\parameter{nonlinear}{\Boolean}{
*Accountfornonlinearcolorshiftsduetointernalscattering?Seethe
*maintextfordetails.\default{Don'taccountforthemand
*preservethetexturecolors,i.e.\code{false}}
*}
*}
*
*\renderings{
*\rendering{Arenderingwiththedefaultparameters}{bsdf_plastic_default}
*\rendering{Arenderingwithcustomparameters(\lstref{plasticshiny})}
*{bsdf_plastic_shiny}
*}
*
*\vspace{3mm}
*Thisplugindescribesasmoothplasticlikematerialwithinternalscattering.
*ItusestheFresnelreflectionandtransmissioncoefficientstoprovide
*directiondependentspecularanddiffusecomponents.
*Sinceitissimple,realistic,andfast,thismodelisoftenabetterchoice
*thanthe\pluginref{phong},\pluginref{ward},and\pluginref{roughplastic}
*pluginswhenrenderingsmoothplasticlikematerials.
*
*Forconvenience,thismodelallowstospecifyIORvalueseithernumerically,
*orbasedonalistofknownmaterials(see\tblref{dielectriciors}for
*anoverview).
*
*Notethatthispluginisquitesimilartowhatonewouldgetbyapplyingthe
*\pluginref{coating}plugintothe\pluginref{diffuse}material.Themain
*differenceisthatthispluginissignificantlyfaster,whileatthesame
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

27/84

9/12/2016

mitApi

*timecausinglessvariance.Furthermore,itaccountsformultiple
*interreflectionsinsidethematerial(readonfordetails),whichavoids
*aseriousenergylossproblemoftheaforementionedplugin
*combination.
*\newpage
*
*\begin{xml}[caption=Ashinymaterialwhosediffusereflectanceis
*specifiedusingsRGB,label=lst:plasticshiny]
*<bsdftype="plastic">
*<srgbname="diffuseReflectance"value="#18455c"/>
*<floatname="intIOR"value="1.9"/>
*</bsdf>
*\end{xml}
*
*\renderings{
*\medrendering{Diffusetexturedrendering}{bsdf_plastic_diffuse}
*\medrendering{Plasticmodel,\code{nonlinear=false}}{bsdf_plastic_preserve}
*\medrendering{Plasticmodel,\code{nonlinear=true}}{bsdf_plastic_nopreserve}
*\caption{
*\label{fig:plasticnonlinear}
*Whenaskedtodoso,thismodelcanaccountforsubtlenonlinearcolorshiftsdue
*tointernalscatteringprocesses.Theaboveimagesshowatextured
*objectfirstrenderedusing\pluginref{diffuse},then
*\pluginref{plastic}withthedefaultparameters,andfinallyusing
*\pluginref{plastic}andsupportfornonlinearcolorshifts.
*}
*}
*
*\subsubsection*{Internalscattering}
*Internally,thisismodelsimulatestheinteractionoflightwithadiffuse
*basesurfacecoatedbyathindielectriclayer.Thisisaconvenient
*abstractionratherthanarestriction.Inotherwords,therearemany
*materialsthatcanberenderedwiththismodel,eveniftheymightnot
*fitthisdescriptionperfectlywell.
*
*\begin{figure}[h]
*\setcounter{subfigure}{0}
*\centering
*\subfloat[Attheboundary,incidentilluminationispartly\mbox{reflected}andrefracted]
*{\includegraphics[width=4.9cm]{images/bsdf_plastic_intscat_1.pdf}}\hfill
*\subfloat[Therefractedportionscattersdiffuselyatthebaselayer]
*{\includegraphics[width=4.9cm]{images/bsdf_plastic_intscat_2.pdf}}\hfill
*\subfloat[Someoftheilluminationundergoesfurtherinternalscatteringevents]
*{\includegraphics[width=4.9cm]{images/bsdf_plastic_intscat_3.pdf}}
*\caption{
*\label{fig:plasticintscat}
*Anillustrationofthescatteringeventsthatareinternally
*handledbythisplugin}
*\end{figure}
*
*Givenilluminationthatisincidentuponsuchamaterial,aportion
*oftheilluminationisspecularlyreflectedatthematerial
*boundary,whichresultsinasharpreflectioninthemirrordirection
*(\subfigref{plasticintscat}{a}).
*Theremainingilluminationrefractsintothematerial,whereit
*scattersfromthediffusebaselayer.(\subfigref{plasticintscat}{b}).
*Whilesomeofthediffuselyscatteredilluminationisableto
*directlyrefractoutwardsagain,theremainderisreflectedfromthe
*interiorsideofthedielectricboundaryandwillinfactremain
*trappedinsidethematerialforsomenumberofinternalscattering
*eventsuntilitisfinallyabletoescape(\subfigref{plasticintscat}{c}).
*
*Duetothemathematicalsimplicityofthissetup,itispossibletowork
*outthecorrectformofthemodelwithoutactuallyhavingtosimulate
*thepotentiallylargenumberofinternalscatteringevents.
*
*Notethatduetotheinternalscattering,thediffusecolorofthe
*materialisinpracticeslightlydifferentfromthecolorofthe
*baselayeronitsowninparticular,thematerialcolorwilltendtoshifttowards
*darkercolorswithhighersaturation.Sincethiscanbecounterintuitivewhen
*usingbitmaptextures,thesecolorshiftsaredisabledbydefault.Specify
*theparameter\code{nonlinear=true}toenablethem.\figref{plasticnonlinear}
*illustratestheresultingchange.Thiseffectisalsoseeninreallife,
*forinstanceapieceofwoodwilllookslightlydarkeraftercoatingit
*withalayerofvarnish.
*/
classSmoothPlastic:publicBSDF{
public:

SmoothPlastic(constProperties&props):BSDF(props){

/*Specifiestheinternalindexofrefractionattheinterface*/
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

28/84

9/12/2016

mitApi

FloatintIOR=lookupIOR(props,"intIOR","polypropylene");

/*Specifiestheexternalindexofrefractionattheinterface*/
FloatextIOR=lookupIOR(props,"extIOR","air");

if(intIOR<0||extIOR<0)

Log(EError,"Theinteriorandexteriorindicesof"

"refractionmustbepositive!");

m_eta=intIOR/extIOR;

m_specularReflectance=newConstantSpectrumTexture(

props.getSpectrum("specularReflectance",Spectrum(1.0f)));
m_diffuseReflectance=newConstantSpectrumTexture(

props.getSpectrum("diffuseReflectance",Spectrum(0.5f)));

m_nonlinear=props.getBoolean("nonlinear",false);

m_specularSamplingWeight=0.0f;

SmoothPlastic(Stream*stream,InstanceManager*manager)

:BSDF(stream,manager){

m_eta=stream>readFloat();

m_nonlinear=stream>readBool();

m_specularReflectance=static_cast<Texture*>(manager>getInstance(stream));

m_diffuseReflectance=static_cast<Texture*>(manager>getInstance(stream));

configure();
}

voidserialize(Stream*stream,InstanceManager*manager)const{

BSDF::serialize(stream,manager);

voidconfigure(){

/*Verifytheinputparametersandfixthemifnecessary*/

m_specularReflectance=ensureEnergyConservation(

m_specularReflectance,"specularReflectance",1.0f);

m_diffuseReflectance=ensureEnergyConservation(

m_diffuseReflectance,"diffuseReflectance",1.0f);

/*NumericallyapproximatethediffuseFresnelreflectance*/
m_fdrInt=fresnelDiffuseReflectance(1/m_eta,false);
m_fdrExt=fresnelDiffuseReflectance(m_eta,false);

/*Computeweightsthatfurthersteersamplestowards
thespecularordiffusecomponents*/
FloatdAvg=m_diffuseReflectance>getAverage().getLuminance(),

sAvg=m_specularReflectance>getAverage().getLuminance();

m_specularSamplingWeight=sAvg/(dAvg+sAvg);

m_invEta2=1/(m_eta*m_eta);

m_usesRayDifferentials=

m_specularReflectance>usesRayDifferentials()||

m_diffuseReflectance>usesRayDifferentials();

m_components.clear();
m_components.push_back(EDeltaReflection|EFrontSide

|(m_specularReflectance>isConstant()?0:ESpatiallyVarying));
m_components.push_back(EDiffuseReflection|EFrontSide

|(m_diffuseReflectance>isConstant()?0:ESpatiallyVarying));

BSDF::configure();

SpectrumgetDiffuseReflectance(constIntersection&its)const{

returnm_diffuseReflectance>eval(its)*(1m_fdrExt);
}

SpectrumgetSpecularReflectance(constIntersection&its)const{

returnm_specularReflectance>eval(its);
}

stream>writeFloat(m_eta);
stream>writeBool(m_nonlinear);
manager>serialize(stream,m_specularReflectance.get());
manager>serialize(stream,m_diffuseReflectance.get());

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

29/84

9/12/2016

mitApi

voidaddChild(conststd::string&name,ConfigurableObject*child){

if(child>getClass()>derivesFrom(MTS_CLASS(Texture))){

if(name=="specularReflectance")

m_specularReflectance=static_cast<Texture*>(child);

elseif(name=="diffuseReflectance")

m_diffuseReflectance=static_cast<Texture*>(child);

else

BSDF::addChild(name,child);

}else{

BSDF::addChild(name,child);

}
}

///Reflectioninlocalcoordinates
inlineVectorreflect(constVector&wi)const{

returnVector(wi.x,wi.y,wi.z);
}

Spectrumeval(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolhasSpecular=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0)

&&measure==EDiscrete;

boolhasDiffuse=(bRec.typeMask&EDiffuseReflection)

&&(bRec.component==1||bRec.component==1)

&&measure==ESolidAngle;

if(Frame::cosTheta(bRec.wo)<=0||Frame::cosTheta(bRec.wi)<=0)

returnSpectrum(0.0f);

FloatFi=fresnelDielectricExt(Frame::cosTheta(bRec.wi),m_eta);

if(hasSpecular){

/*Checkiftheprovideddirectionpairmatchesanideal

specularreflection;toleratesomeroundofferrors*/

if(std::abs(dot(reflect(bRec.wi),bRec.wo)1)<DeltaEpsilon)

returnm_specularReflectance>eval(bRec.its)*Fi;
}elseif(hasDiffuse){

FloatFo=fresnelDielectricExt(Frame::cosTheta(bRec.wo),m_eta);

Spectrumdiff=m_diffuseReflectance>eval(bRec.its);

if(m_nonlinear)

diff/=Spectrum(1.0f)diff*m_fdrInt;
else

diff/=1m_fdrInt;

returndiff*(warp::squareToCosineHemispherePdf(bRec.wo)

*m_invEta2*(1Fi)*(1Fo));

returnSpectrum(0.0f);

Floatpdf(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolhasSpecular=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0);

boolhasDiffuse=(bRec.typeMask&EDiffuseReflection)

&&(bRec.component==1||bRec.component==1);

if(Frame::cosTheta(bRec.wo)<=0||Frame::cosTheta(bRec.wi)<=0)

return0.0f;

FloatprobSpecular=hasSpecular?1.0f:0.0f;
if(hasSpecular&&hasDiffuse){

FloatFi=fresnelDielectricExt(Frame::cosTheta(bRec.wi),m_eta);

probSpecular=(Fi*m_specularSamplingWeight)/

(Fi*m_specularSamplingWeight+

(1Fi)*(1m_specularSamplingWeight));
}

if(hasSpecular&&measure==EDiscrete){

/*Checkiftheprovideddirectionpairmatchesanideal

specularreflection;toleratesomeroundofferrors*/

if(std::abs(dot(reflect(bRec.wi),bRec.wo)1)<DeltaEpsilon)

returnprobSpecular;
}elseif(hasDiffuse&&measure==ESolidAngle){

returnwarp::squareToCosineHemispherePdf(bRec.wo)*(1probSpecular);
}

return0.0f;

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

30/84

9/12/2016

mitApi

Spectrumsample(BSDFSamplingRecord&bRec,constPoint2&sample)const{

boolhasSpecular=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0);

boolhasDiffuse=(bRec.typeMask&EDiffuseReflection)

&&(bRec.component==1||bRec.component==1);

if((!hasDiffuse&&!hasSpecular)||Frame::cosTheta(bRec.wi)<=0)

returnSpectrum(0.0f);

FloatFi=fresnelDielectricExt(Frame::cosTheta(bRec.wi),m_eta);

bRec.eta=1.0f;
if(hasDiffuse&&hasSpecular){

FloatprobSpecular=(Fi*m_specularSamplingWeight)/

(Fi*m_specularSamplingWeight+

(1Fi)*(1m_specularSamplingWeight));

/*Importancesamplewrt.theFresnelreflectance*/
if(sample.x<probSpecular){

bRec.sampledComponent=0;

bRec.sampledType=EDeltaReflection;

bRec.wo=reflect(bRec.wi);

returnm_specularReflectance>eval(bRec.its)

*Fi/probSpecular;
}else{

bRec.sampledComponent=1;

bRec.sampledType=EDiffuseReflection;

bRec.wo=warp::squareToCosineHemisphere(Point2(

(sample.xprobSpecular)/(1probSpecular),

sample.y

));

FloatFo=fresnelDielectricExt(Frame::cosTheta(bRec.wo),m_eta);

returndiff*(m_invEta2*(1Fi)*(1Fo)/(1probSpecular));

}
}elseif(hasSpecular){

bRec.sampledComponent=0;

bRec.sampledType=EDeltaReflection;

bRec.wo=reflect(bRec.wi);

returnm_specularReflectance>eval(bRec.its)*Fi;
}else{

bRec.sampledComponent=1;

bRec.sampledType=EDiffuseReflection;

bRec.wo=warp::squareToCosineHemisphere(sample);

FloatFo=fresnelDielectricExt(Frame::cosTheta(bRec.wo),m_eta);

Spectrumdiff=m_diffuseReflectance>eval(bRec.its);
if(m_nonlinear)

diff/=Spectrum(1.0f)diff*m_fdrInt;
else

diff/=1m_fdrInt;

returndiff*(m_invEta2*(1Fi)*(1Fo));

Spectrumsample(BSDFSamplingRecord&bRec,Float&pdf,constPoint2&sample)const{

boolhasSpecular=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0);

boolhasDiffuse=(bRec.typeMask&EDiffuseReflection)

&&(bRec.component==1||bRec.component==1);

if((!hasDiffuse&&!hasSpecular)||Frame::cosTheta(bRec.wi)<=0)

returnSpectrum(0.0f);

FloatFi=fresnelDielectricExt(Frame::cosTheta(bRec.wi),m_eta);

bRec.eta=1.0f;
if(hasDiffuse&&hasSpecular){

FloatprobSpecular=(Fi*m_specularSamplingWeight)/

(Fi*m_specularSamplingWeight+

Spectrumdiff=m_diffuseReflectance>eval(bRec.its);
if(m_nonlinear)

diff/=Spectrum(1.0f)diff*m_fdrInt;
else

diff/=1m_fdrInt;

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

31/84

9/12/2016

mitApi

(1Fi)*(1m_specularSamplingWeight));

/*Importancesamplewrt.theFresnelreflectance*/
if(sample.x<probSpecular){

bRec.sampledComponent=0;

bRec.sampledType=EDeltaReflection;

bRec.wo=reflect(bRec.wi);

pdf=probSpecular;

returnm_specularReflectance>eval(bRec.its)

*Fi/probSpecular;
}else{

bRec.sampledComponent=1;

bRec.sampledType=EDiffuseReflection;

bRec.wo=warp::squareToCosineHemisphere(Point2(

(sample.xprobSpecular)/(1probSpecular),

sample.y

));

FloatFo=fresnelDielectricExt(Frame::cosTheta(bRec.wo),m_eta);

Spectrumdiff=m_diffuseReflectance>eval(bRec.its);
if(m_nonlinear)

diff/=Spectrum(1.0f)diff*m_fdrInt;
else

diff/=1m_fdrInt;

pdf=(1probSpecular)*

warp::squareToCosineHemispherePdf(bRec.wo);

returndiff*(m_invEta2*(1Fi)*(1Fo)/(1probSpecular));

}
}elseif(hasSpecular){

bRec.sampledComponent=0;

bRec.sampledType=EDeltaReflection;

bRec.wo=reflect(bRec.wi);

pdf=1;

returnm_specularReflectance>eval(bRec.its)*Fi;
}else{

bRec.sampledComponent=1;

bRec.sampledType=EDiffuseReflection;

bRec.wo=warp::squareToCosineHemisphere(sample);

FloatFo=fresnelDielectricExt(Frame::cosTheta(bRec.wo),m_eta);

Spectrumdiff=m_diffuseReflectance>eval(bRec.its);
if(m_nonlinear)

diff/=Spectrum(1.0f)diff*m_fdrInt;
else

diff/=1m_fdrInt;

pdf=warp::squareToCosineHemispherePdf(bRec.wo);

returndiff*(m_invEta2*(1Fi)*(1Fo));

FloatgetRoughness(constIntersection&its,intcomponent)const{

Assert(component==0||component==1);

std::stringtoString()const{

std::ostringstreamoss;

oss<<"SmoothPlastic["<<endl

<<"id=\""<<getID()<<"\","<<endl

<<"specularReflectance="<<indent(m_specularReflectance>toString())<<","<<endl

<<"diffuseReflectance="<<indent(m_diffuseReflectance>toString())<<","<<endl

<<"specularSamplingWeight="<<m_specularSamplingWeight<<","<<endl

<<"diffuseSamplingWeight="<<(1m_specularSamplingWeight)<<","<<endl

<<"nonlinear="<<m_nonlinear<<","<<endl

<<"eta="<<m_eta<<","<<endl

<<"fdrInt="<<m_fdrInt<<","<<endl

<<"fdrExt="<<m_fdrExt<<endl

<<"]";

returnoss.str();
}

if(component==0)

return0.0f;
else

returnstd::numeric_limits<Float>::infinity();

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

32/84

9/12/2016

mitApi

Shader*createShader(Renderer*renderer)const;

MTS_DECLARE_CLASS()
private:

Floatm_fdrInt,m_fdrExt,m_eta,m_invEta2;

ref<Texture>m_diffuseReflectance;

ref<Texture>m_specularReflectance;

Floatm_specularSamplingWeight;

boolm_nonlinear;
};
/**
*Smoothplasticshaderitisreallyhopelesstovisualize
*thismaterialintheVPLrenderer,solet'strytodoatleast
*somethingthatsuggeststhepresenceofaspecularlyreflecting
*dielectricmaterialwithsomethingdiffuseunderneath.
*/
classSmoothPlasticShader:publicShader{
public:

SmoothPlasticShader(Renderer*renderer,constTexture*specularReflectance,

constTexture*diffuseReflectance,Floateta):Shader(renderer,EBSDFShader),

m_specularReflectance(specularReflectance),

m_diffuseReflectance(diffuseReflectance){

m_specularReflectanceShader=renderer>registerShaderForResource(m_specularReflectance.get());

m_diffuseReflectanceShader=renderer>registerShaderForResource(m_diffuseReflectance.get());

m_alpha=0.4f;

m_R0=fresnelDielectricExt(1.0f,eta);

boolisComplete()const{

returnm_specularReflectanceShader.get()!=NULL&&

m_diffuseReflectanceShader.get()!=NULL;
}

voidputDependencies(std::vector<Shader*>&deps){

deps.push_back(m_specularReflectanceShader.get());

deps.push_back(m_diffuseReflectanceShader.get());
}

voidcleanup(Renderer*renderer){

renderer>unregisterShaderForResource(m_specularReflectance.get());

renderer>unregisterShaderForResource(m_diffuseReflectance.get());
}

voidresolve(constGPUProgram*program,conststd::string&evalName,std::vector<int>&parameterIDs)const

voidbind(GPUProgram*program,conststd::vector<int>&parameterIDs,int&textureUnitOffset)const{

program>setParameter(parameterIDs[0],m_alpha);

program>setParameter(parameterIDs[1],m_R0);
}

voidgenerateCode(std::ostringstream&oss,

conststd::string&evalName,

conststd::vector<std::string>&depNames)const{

oss<<"uniformfloat"<<evalName<<"_alpha;"<<endl

<<"uniformfloat"<<evalName<<"_R0;"<<endl

<<endl

<<"float"<<evalName<<"_D(vec3m){"<<endl

<<"floatct=cosTheta(m);"<<endl

<<"if(cosTheta(m)<=0.0)"<<endl

<<"return0.0;"<<endl

<<"floatex=tanTheta(m)/"<<evalName<<"_alpha;"<<endl

<<"returnexp((ex*ex))/(pi*"<<evalName<<"_alpha"<<endl

<<"*"<<evalName<<"_alpha*pow(cosTheta(m),4.0));"<<endl

<<"}"<<endl

<<endl

<<"float"<<evalName<<"_G(vec3m,vec3wi,vec3wo){"<<endl

<<"if((dot(wi,m)*cosTheta(wi))<=0||"<<endl

<<"(dot(wo,m)*cosTheta(wo))<=0)"<<endl

<<"return0.0;"<<endl

<<"floatnDotM=cosTheta(m);"<<endl

<<"returnmin(1.0,min("<<endl

<<"abs(2*nDotM*cosTheta(wo)/dot(wo,m)),"<<endl

<<"abs(2*nDotM*cosTheta(wi)/dot(wi,m))));"<<endl

<<"}"<<endl

<<endl

parameterIDs.push_back(program>getParameterID(evalName+"_alpha",false));
parameterIDs.push_back(program>getParameterID(evalName+"_R0",false));

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

33/84

9/12/2016

mitApi

<<"float"<<evalName<<"_schlick(floatct){"<<endl

<<"floatctSqr=ct*ct,ct5=ctSqr*ctSqr*ct;"<<endl

<<"return"<<evalName<<"_R0+(1.0"<<evalName<<"_R0)*ct5;"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"(vec2uv,vec3wi,vec3wo){"<<endl

<<"if(cosTheta(wi)<=0||cosTheta(wo)<=0)"<<endl

<<"returnvec3(0.0);"<<endl

<<"vec3H=normalize(wi+wo);"<<endl

<<"vec3specRef="<<depNames[0]<<"(uv);"<<endl

<<"vec3diffuseRef="<<depNames[1]<<"(uv);"<<endl

<<"floatD="<<evalName<<"_D(H)"<<";"<<endl

<<"floatG="<<evalName<<"_G(H,wi,wo);"<<endl

<<"floatF="<<evalName<<"_schlick(1dot(wi,H));"<<endl

<<"returnspecRef*(F*D*G/(4*cosTheta(wi)))+"<<endl

<<"diffuseRef*((1F)*cosTheta(wo)*inv_pi);"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"_diffuse(vec2uv,vec3wi,vec3wo){"<<endl

<<"if(cosTheta(wi)<0.0||cosTheta(wo)<0.0)"<<endl

<<"
returnvec3(0.0);"<<endl

<<"vec3diffuseRef="<<depNames[1]<<"(uv);"<<endl

<<"returndiffuseRef*inv_pi*cosTheta(wo);"<<endl

<<"}"<<endl;

MTS_DECLARE_CLASS()
private:

ref<constTexture>m_specularReflectance;

ref<constTexture>m_diffuseReflectance;

ref<Shader>m_specularReflectanceShader;

ref<Shader>m_diffuseReflectanceShader;

Floatm_alpha,m_R0;
};
Shader*SmoothPlastic::createShader(Renderer*renderer)const{

returnnewSmoothPlasticShader(renderer,

m_specularReflectance.get(),m_diffuseReflectance.get(),m_eta);
}
MTS_IMPLEMENT_CLASS(SmoothPlasticShader,false,Shader)
MTS_IMPLEMENT_CLASS_S(SmoothPlastic,false,BSDF)
MTS_EXPORT_PLUGIN(SmoothPlastic,"SmoothplasticBRDF");
MTS_NAMESPACE_END

https://raw.githubusercontent.com/mmanzi/gradientdomain
mitsuba/7f01a2c044440c774dd88afe05eea4acdc418f2c/src/bsdfs/roughdiffuse.cpp

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

34/84

9/12/2016

mitApi

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

35/84

9/12/2016

mitApi

#include<mitsuba/render/bsdf.h>
#include<mitsuba/hw/basicshader.h>
#include<mitsuba/core/warp.h>
MTS_NAMESPACE_BEGIN
/*!\plugin{roughdiffuse}{Roughdiffusematerial}
*\order{2}
*\icon{bsdf_roughdiffuse}
*\parameters{
*\parameter{reflectance}{\Spectrum\Or\Texture}{
*Specifiesthediffusealbedoofthe
*material.\default{0.5}
*}
*\parameter{alpha}{\Spectrum\Or\Texture}{
*Specifiestheroughnessoftheunresolvedsurfacemicrogeometry
*usingthe\emph{rootmeansquare}(RMS)slopeofthe
*microfacets.\default{0.2}
*}
*\parameter{useFastApprox}{\Boolean}{
*Thisparameterselectsbetweenthefullversionofthemodel
*orafastapproximationthatstillretainsmostqualitativefeatures.
*\default{\texttt{false},i.e.usethehighqualityversion}
*}
*}
*
*\renderings{
*\rendering{Smoothdiffusesurface($\alpha=0$)}
*{bsdf_roughdiffuse_0}
*\rendering{Veryroughdiffusesurface($\alpha=0.7$)}
*{bsdf_roughdiffuse_0_7}
*\vspace{3mm}
*\caption{Theeffectofswitchingfromsmoothtoroughdiffusescattering
*isfairlysubtleonthismodelgenerally,therewillbehigher
*reflectanceatgrazingangles,aswellasanoverallreducedcontrast.}\vspace{3mm}
*}
*
*Thisreflectancemodeldescribestheinteractionoflightwitha\emph{rough}
*diffusematerial,suchasplaster,sand,clay,orconcrete,or``powdery''
*surfaces.TheunderlyingtheorywasdevelopedbyOrenandNayar
*\cite{Oren1994Generalization},whomodelthemicroscopicsurfacestructureas
*unresolvedplanarfacetsarrangedinVshapedgrooves,whereeachfacet
*isanidealdiffusereflector.Themodeltakesintoaccountshadowing,
*masking,aswellasinterreflectionsbetweenthefacets.
*
*Sincetheoriginalpublication,thisapproachhasbeenshownto
*beagoodmatchformanyrealworldmaterials,particularlycompared
*toLambertianscattering,whichdoesnottakesurfaceroughnessintoaccount.
*
*TheimplementationinMitsubausesasurfaceroughnessparameter$\alpha$that
*isslightlydifferentfromtheslopeareavarianceintheoriginal1994paper.
*Thereasonforthischangeistomaketheparameter$\alpha$portable
*acrossdifferentmodels(i.e.\pluginref{roughdielectric},\pluginref{roughplastic},
*\pluginref{roughconductor}).
*
*Togetanintuitionabouttheeffectofthe
*parameter$\alpha$,considerthefollowingapproximateclassification:
*avalueof$\alpha=0.0010.01$correspondstoamaterial
*withslightimperfectionsonanotherwisesmoothsurface(forsuchsmall
*values,themodelwillbehaveidenticallyto\pluginref{diffuse}),$\alpha=0.1$
*isrelativelyrough,and$\alpha=0.30.7$is\emph{extremely}rough
*(e.g.anetchedorgroundsurface).
*
*Notethatthismaterialisonesidedthatis,observedfromthe
*backside,itwillbecompletelyblack.Ifthisisundesirable,
*considerusingthe\pluginref{twosided}BRDFadapterplugin.
*/
classRoughDiffuse:publicBSDF{
public:
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

36/84

9/12/2016

mitApi

RoughDiffuse(constProperties&props)

:BSDF(props){

/*Forbettercompatibilitywithothermodels,supportboth

'reflectance'and'diffuseReflectance'asparameternames*/

m_reflectance=newConstantSpectrumTexture(props.getSpectrum(

props.hasProperty("reflectance")?"reflectance"

:"diffuseReflectance",Spectrum(0.5f)));

RoughDiffuse(Stream*stream,InstanceManager*manager)

:BSDF(stream,manager){

m_reflectance=static_cast<Texture*>(manager>getInstance(stream));

m_alpha=static_cast<Texture*>(manager>getInstance(stream));

m_useFastApprox=stream>readBool();

voidconfigure(){

/*Verifytheinputparameterandfixthemifnecessary*/

m_reflectance=ensureEnergyConservation(m_reflectance,"reflectance",1.0f);

m_components.clear();
m_components.push_back(EGlossyReflection|EFrontSide

|((!m_reflectance>isConstant()||!m_alpha>isConstant())

?ESpatiallyVarying:0));

m_usesRayDifferentials=m_reflectance>usesRayDifferentials()||

m_alpha>usesRayDifferentials();

BSDF::configure();

SpectrumgetDiffuseReflectance(constIntersection&its)const{

returnm_reflectance>eval(its);
}

Spectrumeval(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

if(!(bRec.typeMask&EGlossyReflection)||measure!=ESolidAngle

||Frame::cosTheta(bRec.wi)<=0

||Frame::cosTheta(bRec.wo)<=0)

returnSpectrum(0.0f);

/*ConversionfromBeckmannstyleRMSroughnessto
OrenNayarstyleslopeareavariance.Thefactor
of1/sqrt(2)wasfoundtobeaperfectfitup
toextremeroughnessvalues(>.5),afterwhich
thematchisnotasgoodanymore*/
constFloatconversionFactor=1/std::sqrt((Float)2);

Floatsigma=m_alpha>eval(bRec.its).average()

*conversionFactor;

constFloatsigma2=sigma*sigma;

FloatsinThetaI=Frame::sinTheta(bRec.wi),

sinThetaO=Frame::sinTheta(bRec.wo);

FloatcosPhiDiff=0;
if(sinThetaI>Epsilon&&sinThetaO>Epsilon){

/*Computecos(phiOphiI)usingthehalfangleformulae*/

FloatsinPhiI=Frame::sinPhi(bRec.wi),

cosPhiI=Frame::cosPhi(bRec.wi),

sinPhiO=Frame::sinPhi(bRec.wo),

cosPhiO=Frame::cosPhi(bRec.wo);

cosPhiDiff=cosPhiI*cosPhiO+sinPhiI*sinPhiO;
}

if(m_useFastApprox){

FloatA=1.0f0.5f*sigma2/(sigma2+0.33f),

B=0.45f*sigma2/(sigma2+0.09f),

sinAlpha,tanBeta;

m_useFastApprox=props.getBoolean("useFastApprox",false);
m_alpha=newConstantFloatTexture(props.getFloat("alpha",0.2f));

configure();

if(Frame::cosTheta(bRec.wi)>Frame::cosTheta(bRec.wo)){

sinAlpha=sinThetaO;

tanBeta=sinThetaI/Frame::cosTheta(bRec.wi);
}else{

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

37/84

9/12/2016

mitApi

sinAlpha=sinThetaI;
tanBeta=sinThetaO/Frame::cosTheta(bRec.wo);

returnm_reflectance>eval(bRec.its)

*(INV_PI*Frame::cosTheta(bRec.wo)*(A+B

*std::max(cosPhiDiff,(Float)0.0f)*sinAlpha*tanBeta));
}else{

FloatsinThetaI=Frame::sinTheta(bRec.wi),

sinThetaO=Frame::sinTheta(bRec.wo),

thetaI=math::safe_acos(Frame::cosTheta(bRec.wi)),

thetaO=math::safe_acos(Frame::cosTheta(bRec.wo)),

alpha=std::max(thetaI,thetaO),

beta=std::min(thetaI,thetaO);

FloatsinAlpha,sinBeta,tanBeta;
if(Frame::cosTheta(bRec.wi)>Frame::cosTheta(bRec.wo)){

sinAlpha=sinThetaO;sinBeta=sinThetaI;

tanBeta=sinThetaI/Frame::cosTheta(bRec.wi);
}else{

sinAlpha=sinThetaI;sinBeta=sinThetaO;

tanBeta=sinThetaO/Frame::cosTheta(bRec.wo);
}

Floattmp=sigma2/(sigma2+0.09f),

tmp2=(4*INV_PI*INV_PI)*alpha*beta,

tmp3=2*beta*INV_PI;

FloatC1=1.0f0.5f*sigma2/(sigma2+0.33f),

C2=0.45f*tmp,

C3=0.125f*tmp*tmp2*tmp2,

C4=0.17f*sigma2/(sigma2+0.13f);

if(cosPhiDiff>0)

C2*=sinAlpha;
else

C2*=sinAlphatmp3*tmp3*tmp3;

/*Computetan(0.5*(alpha+beta))usingthehalfangleformulae*/
FloattanHalf=(sinAlpha+sinBeta)/(

math::safe_sqrt(1.0fsinAlpha*sinAlpha)+

math::safe_sqrt(1.0fsinBeta*sinBeta));

Spectrumrho=m_reflectance>eval(bRec.its),

snglScat=rho*(C1+cosPhiDiff*C2*tanBeta+

(1.0fstd::abs(cosPhiDiff))*C3*tanHalf),

dblScat=rho*rho*(C4*(1.0fcosPhiDiff*tmp3*tmp3));

return(snglScat+dblScat)*(INV_PI*Frame::cosTheta(bRec.wo));

Floatpdf(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

if(!(bRec.typeMask&EGlossyReflection)||measure!=ESolidAngle

||Frame::cosTheta(bRec.wi)<=0

||Frame::cosTheta(bRec.wo)<=0)

return0.0f;

Spectrumsample(BSDFSamplingRecord&bRec,constPoint2&sample)const{

if(!(bRec.typeMask&EGlossyReflection)||Frame::cosTheta(bRec.wi)<=0)

returnSpectrum(0.0f);

Spectrumsample(BSDFSamplingRecord&bRec,Float&pdf,constPoint2&sample)const{

if(!(bRec.typeMask&EGlossyReflection)||Frame::cosTheta(bRec.wi)<=0)

returnSpectrum(0.0f);

returnwarp::squareToCosineHemispherePdf(bRec.wo);

bRec.wo=warp::squareToCosineHemisphere(sample);
bRec.eta=1.0f;
bRec.sampledComponent=0;
bRec.sampledType=EGlossyReflection;
returneval(bRec,ESolidAngle)/

warp::squareToCosineHemispherePdf(bRec.wo);

bRec.wo=warp::squareToCosineHemisphere(sample);
bRec.eta=1.0f;
bRec.sampledComponent=0;

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

38/84

9/12/2016

mitApi

bRec.sampledType=EGlossyReflection;
pdf=warp::squareToCosineHemispherePdf(bRec.wo);
returneval(bRec,ESolidAngle)/pdf;

voidaddChild(conststd::string&name,ConfigurableObject*child){

if(child>getClass()>derivesFrom(MTS_CLASS(Texture))){

if(name=="reflectance"||name=="diffuseReflectance")

m_reflectance=static_cast<Texture*>(child);

elseif(name=="alpha")

m_alpha=static_cast<Texture*>(child);

else

BSDF::addChild(name,child);

}else{

BSDF::addChild(name,child);

}
}

voidserialize(Stream*stream,InstanceManager*manager)const{

BSDF::serialize(stream,manager);

FloatgetRoughness(constIntersection&its,intcomponent)const{

returnstd::numeric_limits<Float>::infinity();
}

std::stringtoString()const{

std::ostringstreamoss;

oss<<"RoughDiffuse["<<endl

<<"id=\""<<getID()<<"\","<<endl

<<"reflectance="<<indent(m_reflectance>toString())<<","<<endl

<<"alpha="<<indent(m_alpha>toString())<<","<<endl

<<"useFastApprox="<<m_useFastApprox<<endl

<<"]";

returnoss.str();
}

Shader*createShader(Renderer*renderer)const;

manager>serialize(stream,m_reflectance.get());
manager>serialize(stream,m_alpha.get());
stream>writeBool(m_useFastApprox);

MTS_DECLARE_CLASS()
private:

ref<Texture>m_reflectance;

ref<Texture>m_alpha;

boolm_useFastApprox;
};
//================Hardwareshaderimplementation================
classRoughDiffuseShader:publicShader{
public:

RoughDiffuseShader(Renderer*renderer,constTexture*reflectance,constTexture*alpha)

:Shader(renderer,EBSDFShader),m_reflectance(reflectance),m_alpha(alpha){

m_reflectanceShader=renderer>registerShaderForResource(m_reflectance.get());

m_alphaShader=renderer>registerShaderForResource(m_alpha.get());

boolisComplete()const{

returnm_reflectanceShader.get()!=NULL&&

m_alphaShader.get()!=NULL;
}

voidcleanup(Renderer*renderer){

renderer>unregisterShaderForResource(m_reflectance.get());

renderer>unregisterShaderForResource(m_alpha.get());
}

voidputDependencies(std::vector<Shader*>&deps){

deps.push_back(m_reflectanceShader.get());

deps.push_back(m_alphaShader.get());
}

voidgenerateCode(std::ostringstream&oss,

conststd::string&evalName,

conststd::vector<std::string>&depNames)const{

oss<<"vec3"<<evalName<<"(vec2uv,vec3wi,vec3wo){"<<endl

<<"if(cosTheta(wi)<=0.0||cosTheta(wo)<=0.0)"<<endl

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

39/84

9/12/2016

mitApi

<<"
returnvec3(0.0);"<<endl
<<"floatsigma="<<depNames[1]<<"(uv)[0]*0.70711;"<<endl
<<"floatsigma2=sigma*sigma;"<<endl
<<"floatA=1.00.5*sigma2/(sigma2+0.33);"<<endl
<<"floatB=0.45*sigma2/(sigma2+0.09);"<<endl
<<"floatmaxCos=max(0.0,cosPhi(wi)*cosPhi(wo)+sinPhi(wi)*sinPhi(wo));"<<endl
<<"floatsinAlpha,tanBeta;"<<endl
<<"if(cosTheta(wi)>cosTheta(wo)){"<<endl
<<"sinAlpha=sinTheta(wo);"<<endl
<<"tanBeta=sinTheta(wi)/cosTheta(wi);"<<endl
<<"}else{"<<endl
<<"sinAlpha=sinTheta(wi);"<<endl
<<"tanBeta=sinTheta(wo)/cosTheta(wo);"<<endl
<<"}"<<endl
<<"floatvalue=A+B*maxCos*sinAlpha*tanBeta;"<<endl
<<"return"<<depNames[0]<<"(uv)*inv_pi*cosTheta(wo)*value;"<<endl
<<"}"<<endl
<<endl
<<"vec3"<<evalName<<"_diffuse(vec2uv,vec3wi,vec3wo){"<<endl
<<"if(cosTheta(wi)<=0.0||cosTheta(wo)<=0.0)"<<endl
<<"
returnvec3(0.0);"<<endl
<<"return"<<depNames[0]<<"(uv)*inv_pi*cosTheta(wo);"<<endl
<<"}"<<endl;

MTS_DECLARE_CLASS()
private:

ref<constTexture>m_reflectance;

ref<constTexture>m_alpha;

ref<Shader>m_reflectanceShader;

ref<Shader>m_alphaShader;
};
Shader*RoughDiffuse::createShader(Renderer*renderer)const{

returnnewRoughDiffuseShader(renderer,m_reflectance.get(),m_alpha.get());
}
MTS_IMPLEMENT_CLASS(RoughDiffuseShader,false,Shader)
MTS_IMPLEMENT_CLASS_S(RoughDiffuse,false,BSDF)
MTS_EXPORT_PLUGIN(RoughDiffuse,"RoughdiffuseBRDF")
MTS_NAMESPACE_END

https://raw.githubusercontent.com/mmanzi/gradientdomain
mitsuba/7f01a2c044440c774dd88afe05eea4acdc418f2c/src/bsdfs/roughdielectric.cpp

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

40/84

9/12/2016

mitApi

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

41/84

9/12/2016

mitApi

#include<mitsuba/render/bsdf.h>
#include<mitsuba/render/sampler.h>
#include<mitsuba/hw/basicshader.h>
#include"microfacet.h"
#include"ior.h"
MTS_NAMESPACE_BEGIN
/*!\plugin{roughdielectric}{Roughdielectricmaterial}
*\order{5}
*\icon{bsdf_roughdielectric}
*\parameters{
*\parameter{distribution}{\String}{
*Specifiesthetypeofmicrofacetnormaldistribution
*usedtomodelthesurfaceroughness.
*\vspace{1mm}
*\begin{enumerate}[(i)]
*\item\code{beckmann}:Physicallybaseddistributionderivedfrom
*Gaussianrandomsurfaces.Thisisthedefault.\vspace{1.5mm}
*\item\code{ggx}:TheGGX\cite{Walter07Microfacet}distribution(alsoknownas
*TrowbridgeReitz\cite{Trowbridge19975Average}distribution)
*wasdesignedtobetterapproximatethelongtailsobservedinmeasurements
*ofgroundsurfaces,whicharenotmodeledbytheBeckmanndistribution.
*\vspace{1.5mm}
*\item\code{phong}:AnisotropicPhongdistributionby
*AshikhminandShirley\cite{Ashikhmin2005Anisotropic}.
*Inmostcases,the\code{ggx}and\code{beckmann}distributions
*shouldbepreferred,sincetheyprovidebetterimportancesampling
*andaccurateshadowing/maskingcomputations.
*\vspace{4mm}
*\end{enumerate}
*}
*\parameter{alpha,alphaU,alphaV}{\Float\Or\Texture}{
*Specifiestheroughnessoftheunresolvedsurfacemicrogeometry
*alongthetangentandbitangentdirections.WhentheBeckmann
*distributionisused,thisparameterisequaltothe
*\emph{rootmeansquare}(RMS)slopeofthemicrofacets.
*\code{alpha}isaconvenienceparametertoinitializeboth
*\code{alphaU}and\code{alphaV}tothesamevalue.\default{0.1}.
*}
*\parameter{intIOR}{\Float\Or\String}{Interiorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{bk7}/1.5046}}
*\parameter{extIOR}{\Float\Or\String}{Exteriorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{air}/1.000277}}
*\parameter{sampleVisible}{\Boolean}{
*EnablesasamplingtechniqueproposedbyHeitzandD'Eon~\cite{Heitz1014Importance},
*whichfocusescomputationonthevisiblepartsofthemicrofacetnormal
*distribution,considerablyreducingvarianceinsomecases.
*\default{\code{true},i.e.usevisiblenormalsampling}
*}
*\parameter{specular\showbreakReflectance,\newline
*specular\showbreakTransmittance}{\Spectrum\Or\Texture}{Optional
*factorthatcanbeusedtomodulatethespecularreflection/transmissioncomponent.Note
*thatforphysicalrealism,thisparametershouldneverbetouched.\default{1.0}}
*}\vspace{4mm}
*
*Thispluginimplementsarealisticmicrofacetscatteringmodelforrendering
*roughinterfacesbetweendielectricmaterials,suchasatransitionfromairto
*groundglass.Microfacettheorydescribesroughsurfacesasanarrangementof
*unresolvedandideallyspecularfacets,whosenormaldirectionsaregivenby
*aspeciallychosen\emph{microfacetdistribution}.Byaccountingforshadowing
*andmaskingeffectsbetweenthesefacets,itispossibletoreproducetheimportant
*offspecularreflectionspeaksobservedinrealworldmeasurementsofsuch
*materials.
*\renderings{
*\rendering{Antiglareglass(Beckmann,$\alpha=0.02$)}
*{bsdf_roughdielectric_beckmann_0_0_2.jpg}
*\rendering{Roughglass(Beckmann,$\alpha=0.1$)}
*{bsdf_roughdielectric_beckmann_0_1.jpg}
*}
*
*Thispluginisessentiallythe``roughened''equivalentofthe(smooth)plugin
*\pluginref{dielectric}.Forverylowvaluesof$\alpha$,thetwowill
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

42/84

9/12/2016

mitApi

*beidentical,thoughscenesusingthispluginwilltakelongertorender
*duetotheadditionalcomputationalburdenoftrackingsurfaceroughness.
*
*Theimplementationisbasedonthepaper``MicrofacetModels
*forRefractionthroughRoughSurfaces''byWalteretal.
*\cite{Walter07Microfacet}.Itsupportsthreedifferenttypesofmicrofacet
*distributionsandhasatexturableroughnessparameter.Exteriorand
*interiorIORvaluescanbespecifiedindependently,where``exterior''
*referstothesidethatcontainsthesurfacenormal.Similartothe
*\pluginref{dielectric}plugin,IORvaluescaneitherbespecified
*numerically,orbasedonalistofknownmaterials(see
*\tblref{dielectriciors}foranoverview).Whennoparametersaregiven,
*thepluginactivatesthedefaultsettings,whichdescribeaborosilicate
*glassBK7/airinterfacewithalightamountofroughnessmodeledusinga
*Beckmanndistribution.
*
*Togetanintuitionabouttheeffectofthesurfaceroughnessparameter
*$\alpha$,considerthefollowingapproximateclassification:avalueof
*$\alpha=0.0010.01$correspondstoamaterialwithslightimperfections
*onanotherwisesmoothsurfacefinish,$\alpha=0.1$isrelativelyrough,
*and$\alpha=0.30.7$is\emph{extremely}rough(e.g.anetchedorground
*finish).Valuessignificantlyabovethatareprobablynottoorealistic.
*
*Pleasenotethatwhenusingthisplugin,itiscrucialthatthescenecontains
*meaningfulandmutuallycompatibleindexofrefractionchangessee
*\figref{glassexplanation}foranexampleofwhatthisentails.Also,notethat
*theimportancesamplingimplementationofthismodelisclose,but
*notalwaysaperfectaperfectmatchtotheunderlyingscatteringdistribution,
*particularlyforhighroughnessvaluesandwhenthe\texttt{ggx}
*microfacetdistributionisused.Hence,suchrenderingsmay
*convergeslowly.
*
*\subsubsection*{Technicaldetails}
*Allmicrofacetdistributionsallowthespecificationoftwodistinct
*roughnessvaluesalongthetangentandbitangentdirections.Thiscanbe
*usedtoprovideamaterialwitha``brushed''appearance.Thealignment
*oftheanisotropywillfollowtheUVparameterizationoftheunderlying
*mesh.Thismeansthatsuchananisotropicmaterialcannotbeappliedto
*trianglemeshesthataremissingtexturecoordinates.
*
*SinceMitsuba0.5.1,thispluginusesanewimportancesamplingtechnique
*contributedbyEricHeitzandEugeneD'Eon,whichrestrictsthesampling
*domaintothesetofvisible(unmasked)microfacetnormals.Theprevious
*approachofsamplingallnormalsisstillavailableandcanbeenabled
*bysetting\code{sampleVisible}to\code{false}.
*Notethatthisnewmethodisonlyavailableforthe\code{beckmann}and
*\code{ggx}microfacetdistributions.Whenthe\code{phong}distribution
*isselected,theparameterhasnoeffect.
*
*WhenrenderingwiththePhongmicrofacetdistribution,aconversionis
*usedtoturnthespecifiedBeckmannequivalent$\alpha$roughnessvalue
*intotheexponentparameterofthisdistribution.Thisisdoneinaway,
*suchthatthesamevalue$\alpha$willproduceasimilarappearanceacross
*differentmicrofacetdistributions.
*
*WhenrenderingwiththePhongmicrofacetdistribution,aconversionis
*usedtoturnthespecifiedBeckmannequivalent$\alpha$roughnessvalue
*intotheexponentsofthedistribution.Thisisdoneinaway,suchthat
*thedifferentdistributionsallproduceasimilarappearanceforthe
*samevalueof$\alpha$.
*
*\renderings{
*\rendering{Groundglass(GGX,$\alpha$=0.304,
*\lstref{roughdielectricroughglass})}{bsdf_roughdielectric_ggx_0_304.jpg}
*\rendering{Texturedroughness(\lstref{roughdielectrictextured})}
*{bsdf_roughdielectric_textured.jpg}
*}
*
*\begin{xml}[caption=Amaterialdefinitionforgroundglass,label=lst:roughdielectricroughglass]
*<bsdftype="roughdielectric">
*<stringname="distribution"value="ggx"/>
*<floatname="alpha"value="0.304"/>
*<stringname="intIOR"value="bk7"/>
*<stringname="extIOR"value="air"/>
*</bsdf>
*\end{xml}
*
*\begin{xml}[caption=Atexturecanbeattachedtotheroughnessparameter,label=lst:roughdielectrictextured]
*<bsdftype="roughdielectric">
*<stringname="distribution"value="beckmann"/>
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

43/84

9/12/2016

mitApi

*<floatname="intIOR"value="1.5046"/>
*<floatname="extIOR"value="1.0"/>
*
*<texturename="alpha"type="bitmap">
*<stringname="filename"value="roughness.exr"/>
*</texture>
*</bsdf>
*\end{xml}
*/
classRoughDielectric:publicBSDF{
public:

RoughDielectric(constProperties&props):BSDF(props){

m_specularReflectance=newConstantSpectrumTexture(

props.getSpectrum("specularReflectance",Spectrum(1.0f)));

m_specularTransmittance=newConstantSpectrumTexture(

props.getSpectrum("specularTransmittance",Spectrum(1.0f)));

/*Specifiestheinternalindexofrefractionattheinterface*/
FloatintIOR=lookupIOR(props,"intIOR","bk7");

/*Specifiestheexternalindexofrefractionattheinterface*/
FloatextIOR=lookupIOR(props,"extIOR","air");

if(intIOR<0||extIOR<0||intIOR==extIOR)

Log(EError,"Theinteriorandexteriorindicesof"

"refractionmustbepositiveanddiffer!");

m_eta=intIOR/extIOR;
m_invEta=1/m_eta;

MicrofacetDistributiondistr(props);
m_type=distr.getType();
m_sampleVisible=distr.getSampleVisible();

m_alphaU=newConstantFloatTexture(distr.getAlphaU());
if(distr.getAlphaU()==distr.getAlphaV())

m_alphaV=m_alphaU;
else

m_alphaV=newConstantFloatTexture(distr.getAlphaV());

RoughDielectric(Stream*stream,InstanceManager*manager)
:BSDF(stream,manager){

m_type=(MicrofacetDistribution::EType)stream>readUInt();

m_sampleVisible=stream>readBool();

m_alphaU=static_cast<Texture*>(manager>getInstance(stream));

m_alphaV=static_cast<Texture*>(manager>getInstance(stream));

m_specularReflectance=static_cast<Texture*>(manager>getInstance(stream));

m_specularTransmittance=static_cast<Texture*>(manager>getInstance(stream));

m_eta=stream>readFloat();

m_invEta=1/m_eta;

voidserialize(Stream*stream,InstanceManager*manager)const{

BSDF::serialize(stream,manager);

voidconfigure(){

unsignedintextraFlags=0;

if(m_alphaU!=m_alphaV)

extraFlags|=EAnisotropic;

if(!m_alphaU>isConstant()||!m_alphaV>isConstant())

extraFlags|=ESpatiallyVarying;

m_components.clear();
m_components.push_back(EGlossyReflection|EFrontSide

|EBackSide|EUsesSampler|extraFlags

|(m_specularReflectance>isConstant()?0:ESpatiallyVarying));
m_components.push_back(EGlossyTransmission|EFrontSide

configure();

stream>writeUInt((uint32_t)m_type);
stream>writeBool(m_sampleVisible);
manager>serialize(stream,m_alphaU.get());
manager>serialize(stream,m_alphaV.get());
manager>serialize(stream,m_specularReflectance.get());
manager>serialize(stream,m_specularTransmittance.get());
stream>writeFloat(m_eta);

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

44/84

9/12/2016

mitApi

|EBackSide|EUsesSampler|ENonSymmetric|extraFlags
|(m_specularTransmittance>isConstant()?0:ESpatiallyVarying));

/*Verifytheinputparametersandfixthemifnecessary*/
m_specularReflectance=ensureEnergyConservation(

m_specularReflectance,"specularReflectance",1.0f);
m_specularTransmittance=ensureEnergyConservation(

m_specularTransmittance,"specularTransmittance",1.0f);

m_usesRayDifferentials=

m_alphaU>usesRayDifferentials()||

m_alphaV>usesRayDifferentials()||

m_specularReflectance>usesRayDifferentials()||

m_specularTransmittance>usesRayDifferentials();

BSDF::configure();

Spectrumeval(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

if(measure!=ESolidAngle||Frame::cosTheta(bRec.wi)==0)

returnSpectrum(0.0f);

/*Determinethetypeofinteraction*/
boolreflect=Frame::cosTheta(bRec.wi)

*Frame::cosTheta(bRec.wo)>0;

VectorH;
if(reflect){

/*Stopifthiscomponentwasnotrequested*/

if((bRec.component!=1&&bRec.component!=0)

||!(bRec.typeMask&EGlossyReflection))

returnSpectrum(0.0f);

/*Calculatethereflectionhalfvector*/

H=normalize(bRec.wo+bRec.wi);
}else{

/*Stopifthiscomponentwasnotrequested*/

if((bRec.component!=1&&bRec.component!=1)

||!(bRec.typeMask&EGlossyTransmission))

returnSpectrum(0.0f);

/*Calculatethetransmissionhalfvector*/
Floateta=Frame::cosTheta(bRec.wi)>0

?m_eta:m_invEta;

H=normalize(bRec.wi+bRec.wo*eta);

/*Ensurethatthehalfvectorpointsintothe
samehemisphereasthemacrosurfacenormal*/
H*=math::signum(Frame::cosTheta(H));

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/
MicrofacetDistributiondistr(

m_type,

m_alphaU>eval(bRec.its).average(),

m_alphaV>eval(bRec.its).average(),

m_sampleVisible
);

/*Evaluatethemicrofacetnormaldistribution*/
constFloatD=distr.eval(H);
if(D==0)

returnSpectrum(0.0f);

/*Fresnelfactor*/
constFloatF=fresnelDielectricExt(dot(bRec.wi,H),m_eta);

/*Smith'sshadowmaskingfunction*/
constFloatG=distr.G(bRec.wi,bRec.wo,H);

if(reflect){

/*Calculatethetotalamountofreflection*/

Floatvalue=F*D*G/

(4.0f*std::abs(Frame::cosTheta(bRec.wi)));

returnm_specularReflectance>eval(bRec.its)*value;
}else{

Floateta=Frame::cosTheta(bRec.wi)>0.0f?m_eta:m_invEta;

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

45/84

9/12/2016

mitApi

/*Calculatethetotalamountoftransmission*/
FloatsqrtDenom=dot(bRec.wi,H)+eta*dot(bRec.wo,H);
Floatvalue=((1F)*D*G*eta*eta

*dot(bRec.wi,H)*dot(bRec.wo,H))/

(Frame::cosTheta(bRec.wi)*sqrtDenom*sqrtDenom);

/*Missingtermintheoriginalpaper:accountforthesolidangle
compressionwhentracingradiancethisisnecessaryfor
bidirectionalmethods*/
Floatfactor=(bRec.mode==ERadiance)

?(Frame::cosTheta(bRec.wi)>0?m_invEta:m_eta):1.0f;

returnm_specularTransmittance>eval(bRec.its)

*std::abs(value*factor*factor);

Floatpdf(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

if(measure!=ESolidAngle)

return0.0f;

/*Determinethetypeofinteraction*/
boolhasReflection=((bRec.component==1||bRec.component==0)

&&(bRec.typeMask&EGlossyReflection)),
hasTransmission=((bRec.component==1||bRec.component==1)

&&(bRec.typeMask&EGlossyTransmission)),
reflect=Frame::cosTheta(bRec.wi)

*Frame::cosTheta(bRec.wo)>0;

VectorH;
Floatdwh_dwo;

if(reflect){

/*Zeroprobabilityifthiscomponentwasnotrequested*/

if((bRec.component!=1&&bRec.component!=0)

||!(bRec.typeMask&EGlossyReflection))

return0.0f;

/*Jacobianofthehalfdirectionmapping*/

dwh_dwo=1.0f/(4.0f*dot(bRec.wo,H));
}else{

/*Zeroprobabilityifthiscomponentwasnotrequested*/

if((bRec.component!=1&&bRec.component!=1)

||!(bRec.typeMask&EGlossyTransmission))

return0.0f;

/*Calculatethetransmissionhalfvector*/
Floateta=Frame::cosTheta(bRec.wi)>0

?m_eta:m_invEta;

H=normalize(bRec.wi+bRec.wo*eta);

/*Jacobianofthehalfdirectionmapping*/
FloatsqrtDenom=dot(bRec.wi,H)+eta*dot(bRec.wo,H);
dwh_dwo=(eta*eta*dot(bRec.wo,H))/(sqrtDenom*sqrtDenom);

/*Ensurethatthehalfvectorpointsintothe
samehemisphereasthemacrosurfacenormal*/
H*=math::signum(Frame::cosTheta(H));

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/
MicrofacetDistributionsampleDistr(

m_type,

m_alphaU>eval(bRec.its).average(),

m_alphaV>eval(bRec.its).average(),

m_sampleVisible
);

/*TrickbyWalteretal.:slightlyscaletheroughnessvaluesto
reduceimportancesamplingweights.Notneededforthe
HeitzandD'Eonsamplingtechnique.*/
if(!m_sampleVisible)

sampleDistr.scaleAlpha(1.2f0.2f*std::sqrt(

std::abs(Frame::cosTheta(bRec.wi))));

/*Calculatethereflectionhalfvector*/
H=normalize(bRec.wo+bRec.wi);

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

46/84

9/12/2016

mitApi

/*Evaluatethemicrofacetmodelsamplingdensityfunction*/
Floatprob=sampleDistr.pdf(math::signum(Frame::cosTheta(bRec.wi))*bRec.wi,H);

if(hasTransmission&&hasReflection){

FloatF=fresnelDielectricExt(dot(bRec.wi,H),m_eta);

prob*=reflect?F:(1F);
}

returnstd::abs(prob*dwh_dwo);

Spectrumsample(BSDFSamplingRecord&bRec,constPoint2&_sample)const{

Point2sample(_sample);

boolhasReflection=((bRec.component==1||bRec.component==0)

&&(bRec.typeMask&EGlossyReflection)),
hasTransmission=((bRec.component==1||bRec.component==1)

&&(bRec.typeMask&EGlossyTransmission)),
sampleReflection=hasReflection;

if(!hasReflection&&!hasTransmission)

returnSpectrum(0.0f);

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/
MicrofacetDistributiondistr(

m_type,

m_alphaU>eval(bRec.its).average(),

m_alphaV>eval(bRec.its).average(),

m_sampleVisible
);

/*TrickbyWalteretal.:slightlyscaletheroughnessvaluesto
reduceimportancesamplingweights.Notneededforthe
HeitzandD'Eonsamplingtechnique.*/
MicrofacetDistributionsampleDistr(distr);
if(!m_sampleVisible)

sampleDistr.scaleAlpha(1.2f0.2f*std::sqrt(

std::abs(Frame::cosTheta(bRec.wi))));

/*SampleM,themicrofacetnormal*/

FloatmicrofacetPDF;

constNormalm=sampleDistr.sample(math::signum(Frame::cosTheta(bRec.wi))*bRec.wi,sample,
microfacetPDF);

if(microfacetPDF==0)

returnSpectrum(0.0f);

FloatcosThetaT;
FloatF=fresnelDielectricExt(dot(bRec.wi,m),cosThetaT,m_eta);
Spectrumweight(1.0f);

if(hasReflection&&hasTransmission){

if(bRec.sampler>next1D()>F)

sampleReflection=false;
}else{

weight=Spectrum(hasReflection?F:(1F));
}

if(sampleReflection){

/*Perfectspecularreflectionbasedonthemicrofacetnormal*/

bRec.wo=reflect(bRec.wi,m);

bRec.eta=1.0f;

bRec.sampledComponent=0;

bRec.sampledType=EGlossyReflection;

weight*=m_specularReflectance>eval(bRec.its);
}else{

if(cosThetaT==0)

returnSpectrum(0.0f);

/*Sidecheck*/
if(Frame::cosTheta(bRec.wi)*Frame::cosTheta(bRec.wo)<=0)

returnSpectrum(0.0f);

/*Perfectspeculartransmissionbasedonthemicrofacetnormal*/
bRec.wo=refract(bRec.wi,m,m_eta,cosThetaT);
bRec.eta=cosThetaT<0?m_eta:m_invEta;
bRec.sampledComponent=1;
bRec.sampledType=EGlossyTransmission;

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

47/84

9/12/2016

mitApi

/*Sidecheck*/
if(Frame::cosTheta(bRec.wi)*Frame::cosTheta(bRec.wo)>=0)

returnSpectrum(0.0f);

/*Radiancemustbescaledtoaccountforthesolidanglecompression
thatoccurswhencrossingtheinterface.*/
Floatfactor=(bRec.mode==ERadiance)

?(cosThetaT<0?m_invEta:m_eta):1.0f;

weight*=m_specularTransmittance>eval(bRec.its)*(factor*factor);

if(m_sampleVisible)

weight*=distr.smithG1(bRec.wo,m);
else

weight*=std::abs(distr.eval(m)*distr.G(bRec.wi,bRec.wo,m)

*dot(bRec.wi,m)/(microfacetPDF*Frame::cosTheta(bRec.wi)));

returnweight;

Spectrumsample(BSDFSamplingRecord&bRec,Float&pdf,constPoint2&_sample)const{

Point2sample(_sample);

boolhasReflection=((bRec.component==1||bRec.component==0)

&&(bRec.typeMask&EGlossyReflection)),
hasTransmission=((bRec.component==1||bRec.component==1)

&&(bRec.typeMask&EGlossyTransmission)),
sampleReflection=hasReflection;

if(!hasReflection&&!hasTransmission)

returnSpectrum(0.0f);

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/
MicrofacetDistributiondistr(

m_type,

m_alphaU>eval(bRec.its).average(),

m_alphaV>eval(bRec.its).average(),

m_sampleVisible
);

/*TrickbyWalteretal.:slightlyscaletheroughnessvaluesto
reduceimportancesamplingweights.Notneededforthe
HeitzandD'Eonsamplingtechnique.*/
MicrofacetDistributionsampleDistr(distr);
if(!m_sampleVisible)

sampleDistr.scaleAlpha(1.2f0.2f*std::sqrt(

std::abs(Frame::cosTheta(bRec.wi))));

/*SampleM,themicrofacetnormal*/

FloatmicrofacetPDF;

constNormalm=sampleDistr.sample(math::signum(Frame::cosTheta(bRec.wi))*bRec.wi,sample,
microfacetPDF);

if(microfacetPDF==0)

returnSpectrum(0.0f);

floattemporaryPdf=microfacetPDF;

FloatcosThetaT;
FloatF=fresnelDielectricExt(dot(bRec.wi,m),cosThetaT,m_eta);
Spectrumweight(1.0f);

if(hasReflection&&hasTransmission){

if(bRec.sampler>next1D()>F){

sampleReflection=false;

temporaryPdf*=1F;

}else{

temporaryPdf*=F;

}
}else{

weight*=hasReflection?F:(1F);
}

Floatdwh_dwo;
if(sampleReflection){

/*Perfectspecularreflectionbasedonthemicrofacetnormal*/

bRec.wo=reflect(bRec.wi,m);

bRec.eta=1.0f;

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

48/84

9/12/2016

mitApi

bRec.sampledComponent=0;
bRec.sampledType=EGlossyReflection;

/*Sidecheck*/
if(Frame::cosTheta(bRec.wi)*Frame::cosTheta(bRec.wo)<=0)

returnSpectrum(0.0f);

weight*=m_specularReflectance>eval(bRec.its);

/*Jacobianofthehalfdirectionmapping*/

dwh_dwo=1.0f/(4.0f*dot(bRec.wo,m));
}else{

if(cosThetaT==0)

returnSpectrum(0.0f);

/*Perfectspeculartransmissionbasedonthemicrofacetnormal*/
bRec.wo=refract(bRec.wi,m,m_eta,cosThetaT);
bRec.eta=cosThetaT<0?m_eta:m_invEta;
bRec.sampledComponent=1;
bRec.sampledType=EGlossyTransmission;

/*Sidecheck*/
if(Frame::cosTheta(bRec.wi)*Frame::cosTheta(bRec.wo)>=0)

returnSpectrum(0.0f);

/*Radiancemustbescaledtoaccountforthesolidanglecompression
thatoccurswhencrossingtheinterface.*/
Floatfactor=(bRec.mode==ERadiance)

?(cosThetaT<0?m_invEta:m_eta):1.0f;

weight*=m_specularTransmittance>eval(bRec.its)*(factor*factor);

/*Jacobianofthehalfdirectionmapping*/
FloatsqrtDenom=dot(bRec.wi,m)+bRec.eta*dot(bRec.wo,m);
dwh_dwo=(bRec.eta*bRec.eta*dot(bRec.wo,m))/(sqrtDenom*sqrtDenom);

if(m_sampleVisible)

weight*=distr.smithG1(bRec.wo,m);
else

weight*=std::abs(distr.eval(m)*distr.G(bRec.wi,bRec.wo,m)

*dot(bRec.wi,m)/(microfacetPDF*Frame::cosTheta(bRec.wi)));

temporaryPdf*=std::abs(dwh_dwo);

pdf=temporaryPdf;
returnweight;

voidaddChild(conststd::string&name,ConfigurableObject*child){

if(child>getClass()>derivesFrom(MTS_CLASS(Texture))){

if(name=="alpha")

m_alphaU=m_alphaV=static_cast<Texture*>(child);

elseif(name=="alphaU")

m_alphaU=static_cast<Texture*>(child);

elseif(name=="alphaV")

m_alphaV=static_cast<Texture*>(child);

elseif(name=="specularReflectance")

m_specularReflectance=static_cast<Texture*>(child);

elseif(name=="specularTransmittance")

m_specularTransmittance=static_cast<Texture*>(child);

else

BSDF::addChild(name,child);

}else{

BSDF::addChild(name,child);

}
}

FloatgetEta()const{

returnm_eta;
}

FloatgetRoughness(constIntersection&its,intcomponent)const{

return0.5f*(m_alphaU>eval(its).average()

+m_alphaV>eval(its).average());
}

std::stringtoString()const{

std::ostringstreamoss;

oss<<"RoughDielectric["<<endl

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

49/84

9/12/2016

mitApi

<<"id=\""<<getID()<<"\","<<endl

<<"distribution="<<MicrofacetDistribution::distributionName(m_type)<<","<<endl

<<"sampleVisible="<<m_sampleVisible<<","<<endl

<<"eta="<<m_eta<<","<<endl

<<"alphaU="<<indent(m_alphaU>toString())<<","<<endl

<<"alphaV="<<indent(m_alphaV>toString())<<","<<endl

<<"specularReflectance="<<indent(m_specularReflectance>toString())<<","<<endl

<<"specularTransmittance="<<indent(m_specularTransmittance>toString())<<endl

<<"]";
returnoss.str();

Shader*createShader(Renderer*renderer)const;

MTS_DECLARE_CLASS()
private:

MicrofacetDistribution::ETypem_type;

ref<Texture>m_specularTransmittance;

ref<Texture>m_specularReflectance;

ref<Texture>m_alphaU,m_alphaV;

Floatm_eta,m_invEta;

boolm_sampleVisible;
};
/*Fakeglassshaderitisreallyhopelesstovisualize
thismaterialintheVPLrenderer,solet'strytodoatleast
somethingthatsuggeststhepresenceofatransparentboundary*/
classRoughDielectricShader:publicShader{
public:

RoughDielectricShader(Renderer*renderer,Floateta):

Shader(renderer,EBSDFShader){

m_flags=ETransparent;

FloatgetAlpha()const{

return0.3f;
}

voidgenerateCode(std::ostringstream&oss,

conststd::string&evalName,

conststd::vector<std::string>&depNames)const{

oss<<"vec3"<<evalName<<"(vec2uv,vec3wi,vec3wo){"<<endl

<<"if(cosTheta(wi)<0.0||cosTheta(wo)<0.0)"<<endl

<<"
returnvec3(0.0);"<<endl

<<"returnvec3(inv_pi*cosTheta(wo));"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"_diffuse(vec2uv,vec3wi,vec3wo){"<<endl

<<"return"<<evalName<<"(uv,wi,wo);"<<endl

<<"}"<<endl;
}

};

MTS_DECLARE_CLASS()

Shader*RoughDielectric::createShader(Renderer*renderer)const{

returnnewRoughDielectricShader(renderer,m_eta);
}
MTS_IMPLEMENT_CLASS(RoughDielectricShader,false,Shader)
MTS_IMPLEMENT_CLASS_S(RoughDielectric,false,BSDF)
MTS_EXPORT_PLUGIN(RoughDielectric,"RoughdielectricBSDF");
MTS_NAMESPACE_END

https://raw.githubusercontent.com/mmanzi/gradientdomain
mitsuba/7f01a2c044440c774dd88afe05eea4acdc418f2c/src/bsdfs/roughconductor.cpp

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

50/84

9/12/2016

mitApi

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

51/84

9/12/2016

mitApi

#include<mitsuba/core/fresolver.h>
#include<mitsuba/render/bsdf.h>
#include<mitsuba/hw/basicshader.h>
#include"microfacet.h"
#include"ior.h"
MTS_NAMESPACE_BEGIN
/*!\plugin{roughconductor}{Roughconductormaterial}
*\order{7}
*\icon{bsdf_roughconductor}
*\parameters{
*\parameter{distribution}{\String}{
*Specifiesthetypeofmicrofacetnormaldistribution
*usedtomodelthesurfaceroughness.
*\vspace{1mm}
*\begin{enumerate}[(i)]
*\item\code{beckmann}:Physicallybaseddistributionderivedfrom
*Gaussianrandomsurfaces.Thisisthedefault.\vspace{1.5mm}
*\item\code{ggx}:TheGGX\cite{Walter07Microfacet}distribution(alsoknownas
*TrowbridgeReitz\cite{Trowbridge19975Average}distribution)
*wasdesignedtobetterapproximatethelongtailsobservedinmeasurements
*ofgroundsurfaces,whicharenotmodeledbytheBeckmanndistribution.
*\vspace{1.5mm}
*\item\code{phong}:AnisotropicPhongdistributionby
*AshikhminandShirley\cite{Ashikhmin2005Anisotropic}.
*Inmostcases,the\code{ggx}and\code{beckmann}distributions
*shouldbepreferred,sincetheyprovidebetterimportancesampling
*andaccurateshadowing/maskingcomputations.
*\vspace{4mm}
*\end{enumerate}
*}
*\parameter{alpha,alphaU,alphaV}{\Float\Or\Texture}{
*Specifiestheroughnessoftheunresolvedsurfacemicrogeometry
*alongthetangentandbitangentdirections.WhentheBeckmann
*distributionisused,thisparameterisequaltothe
*\emph{rootmeansquare}(RMS)slopeofthemicrofacets.
*\code{alpha}isaconvenienceparametertoinitializeboth
*\code{alphaU}and\code{alphaV}tothesamevalue.\default{0.1}.
*}
*\parameter{material}{\String}{Nameofamaterialpreset,see
*\tblref{conductoriors}.\!\default{\texttt{Cu}/copper}}
*\parameter{eta,k}{\Spectrum}{Realandimaginarycomponentsofthematerial'sindexof
*refraction\default{basedonthevalueof\texttt{material}}}
*\parameter{extEta}{\Float\Or\String}{
*Realvaluedindexofrefractionofthesurroundingdielectric,
*oramaterialnameofadielectric\default{\code{air}}
*}
*\parameter{sampleVisible}{\Boolean}{
*EnablesasamplingtechniqueproposedbyHeitzandD'Eon~\cite{Heitz1014Importance},
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

52/84

9/12/2016

mitApi

*whichfocusescomputationonthevisiblepartsofthemicrofacetnormal
*distribution,considerablyreducingvarianceinsomecases.
*\default{\code{true},i.e.usevisiblenormalsampling}
*}
*\parameter{specular\showbreakReflectance}{\Spectrum\Or\Texture}{Optional
*factorthatcanbeusedtomodulatethespecularreflectioncomponent.Note
*thatforphysicalrealism,thisparametershouldneverbetouched.\default{1.0}}
*}
*\vspace{3mm}
*Thispluginimplementsarealisticmicrofacetscatteringmodelforrendering
*roughconductingmaterials,suchasmetals.Itcanbeinterpretedasafancy
*versionoftheCookTorrancemodelandshouldbepreferredover
*heuristicmodelslike\pluginref{phong}and\pluginref{ward}ifpossible.
*\renderings{
*\rendering{Roughcopper(Beckmann,$\alpha=0.1$)}
*{bsdf_roughconductor_copper.jpg}
*\rendering{Verticallybrushedaluminium(AnisotropicPhong,
*$\alpha_u=0.05,\\alpha_v=0.3$),see
*\lstref{roughconductoraluminium}}
*{bsdf_roughconductor_anisotropic_aluminium.jpg}
*}
*
*Microfacettheorydescribesroughsurfacesasanarrangementofunresolved
*andideallyspecularfacets,whosenormaldirectionsaregivenbya
*speciallychosen\emph{microfacetdistribution}.Byaccountingforshadowing
*andmaskingeffectsbetweenthesefacets,itispossibletoreproducethe
*importantoffspecularreflectionspeaksobservedinrealworldmeasurements
*ofsuchmaterials.
*
*Thispluginisessentiallythe``roughened''equivalentofthe(smooth)plugin
*\pluginref{conductor}.Forverylowvaluesof$\alpha$,thetwowill
*beidentical,thoughscenesusingthispluginwilltakelongertorender
*duetotheadditionalcomputationalburdenoftrackingsurfaceroughness.
*
*Theimplementationisbasedonthepaper``MicrofacetModels
*forRefractionthroughRoughSurfaces''byWalteretal.
*\cite{Walter07Microfacet}.Itsupportsthreedifferenttypesofmicrofacet
*distributionsandhasatexturableroughnessparameter.
*Tofacilitatethetedioustaskofspecifyingspectrallyvaryingindexof
*refractioninformation,thisplugincanaccessasetofmeasuredmaterials
*forwhichvisiblespectruminformationwaspubliclyavailable
*(see\tblref{conductoriors}forthefulllist).
*Thereisalsoaspecialmaterialprofilenamed\code{none},whichdisables
*thecomputationofFresnelreflectancesandproducesanidealized
*100%reflectingmirror.
*
*Whennoparametersaregiven,thepluginactivatesthedefaultsettings,
*whichdescribecopperwithamediumamountofroughnessmodeledusinga
*Beckmanndistribution.
*
*Togetanintuitionabouttheeffectofthesurfaceroughnessparameter
*$\alpha$,considerthefollowingapproximateclassification:avalueof
*$\alpha=0.0010.01$correspondstoamaterialwithslightimperfections
*onanotherwisesmoothsurfacefinish,$\alpha=0.1$isrelativelyrough,
*and$\alpha=0.30.7$is\emph{extremely}rough(e.g.anetchedorground
*finish).Valuessignificantlyabovethatareprobablynottoorealistic.
*\vspace{4mm}
*\begin{xml}[caption={Amaterialdefinitionforbrushedaluminium},label=lst:roughconductoraluminium]
*<bsdftype="roughconductor">
*<stringname="material"value="Al"/>
*<stringname="distribution"value="phong"/>
*<floatname="alphaU"value="0.05"/>
*<floatname="alphaV"value="0.3"/>
*</bsdf>
*\end{xml}
*
*\subsubsection*{Technicaldetails}
*Allmicrofacetdistributionsallowthespecificationoftwodistinct
*roughnessvaluesalongthetangentandbitangentdirections.Thiscanbe
*usedtoprovideamaterialwitha``brushed''appearance.Thealignment
*oftheanisotropywillfollowtheUVparameterizationoftheunderlying
*mesh.Thismeansthatsuchananisotropicmaterialcannotbeappliedto
*trianglemeshesthataremissingtexturecoordinates.
*
*\label{sec:visiblenormalsampling}
*SinceMitsuba0.5.1,thispluginusesanewimportancesamplingtechnique
*contributedbyEricHeitzandEugeneD'Eon,whichrestrictsthesampling
*domaintothesetofvisible(unmasked)microfacetnormals.Theprevious
*approachofsamplingallnormalsisstillavailableandcanbeenabled
*bysetting\code{sampleVisible}to\code{false}.
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

53/84

9/12/2016

mitApi

*Notethatthisnewmethodisonlyavailableforthe\code{beckmann}and
*\code{ggx}microfacetdistributions.Whenthe\code{phong}distribution
*isselected,theparameterhasnoeffect.
*
*WhenrenderingwiththePhongmicrofacetdistribution,aconversionis
*usedtoturnthespecifiedBeckmannequivalent$\alpha$roughnessvalue
*intotheexponentparameterofthisdistribution.Thisisdoneinaway,
*suchthatthesamevalue$\alpha$willproduceasimilarappearanceacross
*differentmicrofacetdistributions.
*
*Whenusingthisplugin,youshouldideallycompileMitsubawithsupportfor
*spectralrenderingtogetthemostaccurateresults.Whileitalsoworks
*inRGBmode,thecomputationswillbemoreapproximateinnature.
*Alsonotethatthismaterialisonesidedthatis,observedfromthe
*backside,itwillbecompletelyblack.Ifthisisundesirable,
*considerusingthe\pluginref{twosided}BRDFadapter.
*/
classRoughConductor:publicBSDF{
public:

RoughConductor(constProperties&props):BSDF(props){

ref<FileResolver>fResolver=Thread::getThread()>getFileResolver();

m_specularReflectance=newConstantSpectrumTexture(

props.getSpectrum("specularReflectance",Spectrum(1.0f)));

std::stringmaterialName=props.getString("material","Cu");

SpectrumintEta,intK;
if(boost::to_lower_copy(materialName)=="none"){

intEta=Spectrum(0.0f);

intK=Spectrum(1.0f);
}else{

intEta.fromContinuousSpectrum(InterpolatedSpectrum(

fResolver>resolve("data/ior/"+materialName+".eta.spd")));

intK.fromContinuousSpectrum(InterpolatedSpectrum(

fResolver>resolve("data/ior/"+materialName+".k.spd")));
}

FloatextEta=lookupIOR(props,"extEta","air");

m_eta=props.getSpectrum("eta",intEta)/extEta;
m_k=props.getSpectrum("k",intK)/extEta;

MicrofacetDistributiondistr(props);
m_type=distr.getType();
m_sampleVisible=distr.getSampleVisible();

m_alphaU=newConstantFloatTexture(distr.getAlphaU());
if(distr.getAlphaU()==distr.getAlphaV())

m_alphaV=m_alphaU;
else

m_alphaV=newConstantFloatTexture(distr.getAlphaV());

RoughConductor(Stream*stream,InstanceManager*manager)
:BSDF(stream,manager){

m_type=(MicrofacetDistribution::EType)stream>readUInt();

m_sampleVisible=stream>readBool();

m_alphaU=static_cast<Texture*>(manager>getInstance(stream));

m_alphaV=static_cast<Texture*>(manager>getInstance(stream));

m_specularReflectance=static_cast<Texture*>(manager>getInstance(stream));

m_eta=Spectrum(stream);

m_k=Spectrum(stream);

voidserialize(Stream*stream,InstanceManager*manager)const{

BSDF::serialize(stream,manager);

voidconfigure(){

configure();

stream>writeUInt((uint32_t)m_type);
stream>writeBool(m_sampleVisible);
manager>serialize(stream,m_alphaU.get());
manager>serialize(stream,m_alphaV.get());
manager>serialize(stream,m_specularReflectance.get());
m_eta.serialize(stream);
m_k.serialize(stream);

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

54/84

9/12/2016

mitApi

unsignedintextraFlags=0;
if(m_alphaU!=m_alphaV)

extraFlags|=EAnisotropic;

if(!m_alphaU>isConstant()||!m_alphaV>isConstant()||

!m_specularReflectance>isConstant())

extraFlags|=ESpatiallyVarying;

m_components.clear();
m_components.push_back(EGlossyReflection|EFrontSide|extraFlags);

/*Verifytheinputparametersandfixthemifnecessary*/
m_specularReflectance=ensureEnergyConservation(

m_specularReflectance,"specularReflectance",1.0f);

m_usesRayDifferentials=

m_alphaU>usesRayDifferentials()||

m_alphaV>usesRayDifferentials()||

m_specularReflectance>usesRayDifferentials();

BSDF::configure();

///Helperfunction:reflect\cwiwithrespecttoagivensurfacenormal
inlineVectorreflect(constVector&wi,constNormal&m)const{

return2*dot(wi,m)*Vector(m)wi;
}

Spectrumeval(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

/*Stopifthiscomponentwasnotrequested*/

if(measure!=ESolidAngle||

Frame::cosTheta(bRec.wi)<=0||

Frame::cosTheta(bRec.wo)<=0||

((bRec.component!=1&&bRec.component!=0)||

!(bRec.typeMask&EGlossyReflection)))

returnSpectrum(0.0f);

/*Calculatethereflectionhalfvector*/
VectorH=normalize(bRec.wo+bRec.wi);

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/
MicrofacetDistributiondistr(

m_type,

m_alphaU>eval(bRec.its).average(),

m_alphaV>eval(bRec.its).average(),

m_sampleVisible
);

/*Evaluatethemicrofacetnormaldistribution*/
constFloatD=distr.eval(H);
if(D==0)

returnSpectrum(0.0f);

/*Fresnelfactor*/
constSpectrumF=fresnelConductorExact(dot(bRec.wi,H),m_eta,m_k)*

m_specularReflectance>eval(bRec.its);

/*Smith'sshadowmaskingfunction*/
constFloatG=distr.G(bRec.wi,bRec.wo,H);

/*Calculatethetotalamountofreflection*/
Floatmodel=D*G/(4.0f*Frame::cosTheta(bRec.wi));

returnF*model;

Floatpdf(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

if(measure!=ESolidAngle||

Frame::cosTheta(bRec.wi)<=0||

Frame::cosTheta(bRec.wo)<=0||

((bRec.component!=1&&bRec.component!=0)||

!(bRec.typeMask&EGlossyReflection)))

return0.0f;

/*Calculatethereflectionhalfvector*/
VectorH=normalize(bRec.wo+bRec.wi);

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

55/84

9/12/2016

mitApi

MicrofacetDistributiondistr(

m_type,

m_alphaU>eval(bRec.its).average(),

m_alphaV>eval(bRec.its).average(),

m_sampleVisible
);

if(m_sampleVisible)

returndistr.eval(H)*distr.smithG1(bRec.wi,H)

/(4.0f*Frame::cosTheta(bRec.wi));
else

returndistr.pdf(bRec.wi,H)/(4*absDot(bRec.wo,H));

Spectrumsample(BSDFSamplingRecord&bRec,constPoint2&sample)const{

if(Frame::cosTheta(bRec.wi)<0||

((bRec.component!=1&&bRec.component!=0)||

!(bRec.typeMask&EGlossyReflection)))

returnSpectrum(0.0f);

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/
MicrofacetDistributiondistr(

m_type,

m_alphaU>eval(bRec.its).average(),

m_alphaV>eval(bRec.its).average(),

m_sampleVisible
);

/*SampleM,themicrofacetnormal*/
Floatpdf;
Normalm=distr.sample(bRec.wi,sample,pdf);

if(pdf==0)

returnSpectrum(0.0f);

/*Perfectspecularreflectionbasedonthemicrofacetnormal*/
bRec.wo=reflect(bRec.wi,m);
bRec.eta=1.0f;
bRec.sampledComponent=0;
bRec.sampledType=EGlossyReflection;

/*Sidecheck*/
if(Frame::cosTheta(bRec.wo)<=0)

returnSpectrum(0.0f);

SpectrumF=fresnelConductorExact(dot(bRec.wi,m),

m_eta,m_k)*m_specularReflectance>eval(bRec.its);

Floatweight;
if(m_sampleVisible){

weight=distr.smithG1(bRec.wo,m);
}else{

weight=distr.eval(m)*distr.G(bRec.wi,bRec.wo,m)

*dot(bRec.wi,m)/(pdf*Frame::cosTheta(bRec.wi));
}

returnF*weight;

Spectrumsample(BSDFSamplingRecord&bRec,Float&pdf,constPoint2&sample)const{

if(Frame::cosTheta(bRec.wi)<0||

((bRec.component!=1&&bRec.component!=0)||

!(bRec.typeMask&EGlossyReflection)))

returnSpectrum(0.0f);

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/
MicrofacetDistributiondistr(

m_type,

m_alphaU>eval(bRec.its).average(),

m_alphaV>eval(bRec.its).average(),

m_sampleVisible
);

/*SampleM,themicrofacetnormal*/
FloattemporaryPdf(0);
Normalm=distr.sample(bRec.wi,sample,temporaryPdf);

if(temporaryPdf==0)

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

56/84

9/12/2016

mitApi

returnSpectrum(0.0f);

/*Perfectspecularreflectionbasedonthemicrofacetnormal*/
bRec.wo=reflect(bRec.wi,m);
bRec.eta=1.0f;
bRec.sampledComponent=0;
bRec.sampledType=EGlossyReflection;

/*Sidecheck*/
if(Frame::cosTheta(bRec.wo)<=0)

returnSpectrum(0.0f);

SpectrumF=fresnelConductorExact(dot(bRec.wi,m),

m_eta,m_k)*m_specularReflectance>eval(bRec.its);

Floatweight;
if(m_sampleVisible){

weight=distr.smithG1(bRec.wo,m);
}else{

weight=distr.eval(m)*distr.G(bRec.wi,bRec.wo,m)

*dot(bRec.wi,m)/(temporaryPdf*Frame::cosTheta(bRec.wi));
}

if(weight>0){

/*Jacobianofthehalfdirectionmapping*/

pdf=temporaryPdf/(4.0f*dot(bRec.wo,m));

returnF*weight;
}
returnSpectrum(Float(0));

voidaddChild(conststd::string&name,ConfigurableObject*child){

if(child>getClass()>derivesFrom(MTS_CLASS(Texture))){

if(name=="alpha")

m_alphaU=m_alphaV=static_cast<Texture*>(child);

elseif(name=="alphaU")

m_alphaU=static_cast<Texture*>(child);

elseif(name=="alphaV")

m_alphaV=static_cast<Texture*>(child);

elseif(name=="specularReflectance")

m_specularReflectance=static_cast<Texture*>(child);

else

BSDF::addChild(name,child);

}else{

BSDF::addChild(name,child);

}
}

FloatgetRoughness(constIntersection&its,intcomponent)const{

return0.5f*(m_alphaU>eval(its).average()

+m_alphaV>eval(its).average());
}

std::stringtoString()const{

std::ostringstreamoss;

oss<<"RoughConductor["<<endl

<<"id=\""<<getID()<<"\","<<endl

<<"distribution="<<MicrofacetDistribution::distributionName(m_type)<<","<<endl

<<"sampleVisible="<<m_sampleVisible<<","<<endl

<<"alphaU="<<indent(m_alphaU>toString())<<","<<endl

<<"alphaV="<<indent(m_alphaV>toString())<<","<<endl

<<"specularReflectance="<<indent(m_specularReflectance>toString())<<","<<endl

<<"eta="<<m_eta.toString()<<","<<endl

<<"k="<<m_k.toString()<<endl

<<"]";

returnoss.str();
}

Shader*createShader(Renderer*renderer)const;

MTS_DECLARE_CLASS()
private:

MicrofacetDistribution::ETypem_type;

ref<Texture>m_specularReflectance;

ref<Texture>m_alphaU,m_alphaV;

boolm_sampleVisible;

Spectrumm_eta,m_k;
};
/**
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

57/84

9/12/2016

mitApi

*GLSLportoftheroughconductorshader.Thisversionismuchmore
*approximateitonlysupportstheAshikhminShirleydistribution,
*doeseverythinginRGB,anditusestheSchlickapproximationtothe
*Fresnelreflectanceofconductors.Whentheroughnessislowerthan
*\alpha<0.2,theshaderclampsitto0.2sothatitwillstillperform
*reasonablywellinaVPLbasedpreview.
*/
classRoughConductorShader:publicShader{
public:

RoughConductorShader(Renderer*renderer,constTexture*specularReflectance,

constTexture*alphaU,constTexture*alphaV,constSpectrum&eta,

constSpectrum&k):Shader(renderer,EBSDFShader),

m_specularReflectance(specularReflectance),m_alphaU(alphaU),m_alphaV(alphaV){

m_specularReflectanceShader=renderer>registerShaderForResource(m_specularReflectance.get());

m_alphaUShader=renderer>registerShaderForResource(m_alphaU.get());

m_alphaVShader=renderer>registerShaderForResource(m_alphaV.get());

boolisComplete()const{

returnm_specularReflectanceShader.get()!=NULL&&

m_alphaUShader.get()!=NULL&&

m_alphaVShader.get()!=NULL;
}

voidputDependencies(std::vector<Shader*>&deps){

deps.push_back(m_specularReflectanceShader.get());

deps.push_back(m_alphaUShader.get());

deps.push_back(m_alphaVShader.get());
}

voidcleanup(Renderer*renderer){

renderer>unregisterShaderForResource(m_specularReflectance.get());

renderer>unregisterShaderForResource(m_alphaU.get());

renderer>unregisterShaderForResource(m_alphaV.get());
}

voidresolve(constGPUProgram*program,conststd::string&evalName,std::vector<int>&parameterIDs)const

voidbind(GPUProgram*program,conststd::vector<int>&parameterIDs,int&textureUnitOffset)const{

program>setParameter(parameterIDs[0],m_R0);
}

voidgenerateCode(std::ostringstream&oss,

conststd::string&evalName,

conststd::vector<std::string>&depNames)const{

oss<<"uniformvec3"<<evalName<<"_R0;"<<endl

<<endl

<<"float"<<evalName<<"_D(vec3m,floatalphaU,floatalphaV){"<<endl

<<"floatct=cosTheta(m),ds=1ct*ct;"<<endl

<<"if(ds<=0.0)"<<endl

<<"return0.0f;"<<endl

<<"alphaU=2/(alphaU*alphaU)2;"<<endl

<<"alphaV=2/(alphaV*alphaV)2;"<<endl

<<"floatexponent=(alphaU*m.x*m.x+alphaV*m.y*m.y)/ds;"<<endl

<<"returnsqrt((alphaU+2)*(alphaV+2))*0.15915*pow(ct,exponent);"<<endl

<<"}"<<endl

<<endl

<<"float"<<evalName<<"_G(vec3m,vec3wi,vec3wo){"<<endl

<<"if((dot(wi,m)*cosTheta(wi))<=0||"<<endl

<<"(dot(wo,m)*cosTheta(wo))<=0)"<<endl

<<"return0.0;"<<endl

<<"floatnDotM=cosTheta(m);"<<endl

<<"returnmin(1.0,min("<<endl

<<"abs(2*nDotM*cosTheta(wo)/dot(wo,m)),"<<endl

<<"abs(2*nDotM*cosTheta(wi)/dot(wi,m))));"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"_schlick(floatct){"<<endl

<<"floatctSqr=ct*ct,ct5=ctSqr*ctSqr*ct;"<<endl

<<"return"<<evalName<<"_R0+(vec3(1.0)"<<evalName<<"_R0)*ct5;"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"(vec2uv,vec3wi,vec3wo){"<<endl

<<"if(cosTheta(wi)<=0||cosTheta(wo)<=0)"<<endl

/*Computethereflectanceatperpendicularincidence*/
m_R0=fresnelConductorExact(1.0f,eta,k);

parameterIDs.push_back(program>getParameterID(evalName+"_R0",false));

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

58/84

9/12/2016

mitApi

<<"
returnvec3(0.0);"<<endl

<<"vec3H=normalize(wi+wo);"<<endl

<<"vec3reflectance="<<depNames[0]<<"(uv);"<<endl

<<"floatalphaU=max(0.2,"<<depNames[1]<<"(uv).r);"<<endl

<<"floatalphaV=max(0.2,"<<depNames[2]<<"(uv).r);"<<endl

<<"floatD="<<evalName<<"_D(H,alphaU,alphaV)"<<";"<<endl

<<"floatG="<<evalName<<"_G(H,wi,wo);"<<endl

<<"vec3F="<<evalName<<"_schlick(1dot(wi,H));"<<endl

<<"returnreflectance*F*(D*G/(4*cosTheta(wi)));"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"_diffuse(vec2uv,vec3wi,vec3wo){"<<endl

<<"if(cosTheta(wi)<0.0||cosTheta(wo)<0.0)"<<endl

<<"
returnvec3(0.0);"<<endl

<<"return"<<evalName<<"_R0*inv_pi*inv_pi*cosTheta(wo);"<<endl

<<"}"<<endl;

MTS_DECLARE_CLASS()
private:

ref<constTexture>m_specularReflectance;

ref<constTexture>m_alphaU;

ref<constTexture>m_alphaV;

ref<Shader>m_specularReflectanceShader;

ref<Shader>m_alphaUShader;

ref<Shader>m_alphaVShader;

Spectrumm_R0;
};
Shader*RoughConductor::createShader(Renderer*renderer)const{

returnnewRoughConductorShader(renderer,

m_specularReflectance.get(),m_alphaU.get(),m_alphaV.get(),m_eta,m_k);
}
MTS_IMPLEMENT_CLASS(RoughConductorShader,false,Shader)
MTS_IMPLEMENT_CLASS_S(RoughConductor,false,BSDF)
MTS_EXPORT_PLUGIN(RoughConductor,"RoughconductorBRDF");
MTS_NAMESPACE_END

https://raw.githubusercontent.com/mmanzi/gradientdomain
mitsuba/7f01a2c044440c774dd88afe05eea4acdc418f2c/src/bsdfs/roughcoating.cpp

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

59/84

9/12/2016

mitApi

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

60/84

9/12/2016

mitApi

#include<mitsuba/render/bsdf.h>
#include<mitsuba/hw/basicshader.h>
#include"microfacet.h"
#include"rtrans.h"
#include"ior.h"
MTS_NAMESPACE_BEGIN
/*!\plugin{roughcoating}{Roughdielectriccoating}
*\order{11}
*\icon{bsdf_roughcoating}
*\parameters{
*\parameter{distribution}{\String}{
*Specifiesthetypeofmicrofacetnormaldistribution
*usedtomodelthesurfaceroughness.
*\vspace{1mm}
*\begin{enumerate}[(i)]
*\item\code{beckmann}:Physicallybaseddistributionderivedfrom
*Gaussianrandomsurfaces.Thisisthedefault.\vspace{1.5mm}
*\item\code{ggx}:TheGGX\cite{Walter07Microfacet}distribution(alsoknownas
*TrowbridgeReitz\cite{Trowbridge19975Average}distribution)
*wasdesignedtobetterapproximatethelongtailsobservedinmeasurements
*ofgroundsurfaces,whicharenotmodeledbytheBeckmanndistribution.
*\vspace{1.5mm}
*\item\code{phong}:ClassicalPhongdistribution.
*Inmostcases,the\code{ggx}and\code{beckmann}distributions
*shouldbepreferred,sincetheyprovidebetterimportancesampling
*andaccurateshadowing/maskingcomputations.
*\vspace{4mm}
*\end{enumerate}
*}
*\parameter{alpha}{\Float\Or\Texture}{
*Specifiestheroughnessoftheunresolvedsurfacemicrogeometry.
*WhentheBeckmanndistributionisused,thisparameterisequaltothe
*\emph{rootmeansquare}(RMS)slopeofthemicrofacets.
*\default{0.1}.
*}
*\parameter{sampleVisible}{\Boolean}{
*
Enablesanimprovedimportancesamplingtechnique.Referto
*
pages\pageref{plg:roughconductor}and\pageref{sec:visiblenormalsampling}
*
fordetails.\default{\code{true}}
*}
*\parameter{intIOR}{\Float\Or\String}{Interiorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{bk7}/1.5046}}
*\parameter{extIOR}{\Float\Or\String}{Exteriorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{air}/1.000277}}
*\parameter{thickness}{\Float}{Denotesthethicknessofthelayer(to
*modelabsorptionshouldbespecifiedininverseunitsof\code{sigmaA})\default{1}}
*\parameter{sigmaA}{\Spectrum\Or\Texture}{Theabsorptioncoefficientofthe
*coatinglayer.\default{0,i.e.thereisnoabsorption}}
*\parameter{specular\showbreakReflectance}{\Spectrum\Or\Texture}{Optional
*factorthatcanbeusedtomodulatethespecularreflectioncomponent.Note
*thatforphysicalrealism,thisparametershouldneverbetouched.\default{1.0}}
*\parameter{\Unnamed}{\BSDF}{AnestedBSDFmodelthatshouldbecoated.}
*}
*\renderings{
*\rendering{Roughgoldcoatedwitha\emph{smooth}varnishlayer}
*{bsdf_roughcoating_gold_smooth}
*\rendering{Roughgoldcoatedwitha\emph{rough}($\alpha\!=\!0.03$)varnishlayer}
*{bsdf_roughcoating_gold_rough}
*}
*
*Thispluginimplementsa\emph{very}approximate\footnote{
*Themodelonlyaccountsforroughness
*inthespecularreflectionandFresneltransmittancethroughtheinterface.
*Theinteriormodelreceivesincidentillumination
*thatistransformed\emph{asif}thecoatingwassmooth.While
*that'snotquitecorrect,itisaconvenientworkaroundwhenthe
*\pluginref{coating}pluginproducesspecularhighlightsthataretoosharp.}
*modelthatsimulatesaroughdielectriccoating.Itisessentiallythe
*roughenedversionof\pluginref{coating}.
*AnyBSDFinMitsubacanbecoatedusingthispluginandmultiplecoating
*layerscanevenbeappliedinsequence,whichallowsdesigninginteresting
*custommaterials.Thecoatinglayercanoptionallybetinted(i.e.filled
*withanabsorbingmedium),inwhichcasethismodelalsoaccountsforthe
*directionallydependentabsorptionwithinthelayer.
*
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

61/84

9/12/2016

mitApi

*Notethattheplugindiscardsilluminationthatundergoesinternal
*reflectionwithinthecoating.Thiscanleadtoanoticeableenergy
*lossformaterialsthatreflectmuchoftheirenergynearorbelowthecritical
*angle(i.e.diffuseorveryroughmaterials).
*
*Theimplementationhereismotivatedbythepaper
*``ArbitrarilyLayeredMicroFacetSurfaces''byWeidlichand
*Wilkie\cite{Weidlich2007Arbitrarily},thoughtheimplementation
*worksdifferently.
*/
classRoughCoating:publicBSDF{
public:

///\sarefractTo()

enumEDestination{

EInterior=0,

EExterior=1

};

RoughCoating(constProperties&props):BSDF(props){

/*Specifiestheinternalindexofrefractionattheinterface*/

FloatintIOR=lookupIOR(props,"intIOR","bk7");

/*Specifiestheexternalindexofrefractionattheinterface*/
FloatextIOR=lookupIOR(props,"extIOR","air");

if(intIOR<0||extIOR<0||intIOR==extIOR)

Log(EError,"Theinteriorandexteriorindicesof"

"refractionmustbepositiveanddiffer!");

m_eta=intIOR/extIOR;
m_invEta=1/m_eta;

/*Specifiestheabsorptionwithinthelayer*/
m_sigmaA=newConstantSpectrumTexture(

props.getSpectrum("sigmaA",Spectrum(0.0f)));

/*Specifiesthelayer'sthicknessusingtheinverseunitsofsigmaA*/
m_thickness=props.getFloat("thickness",1);

/*Specifiesamultiplierforthespecularreflectancecomponent*/
m_specularReflectance=newConstantSpectrumTexture(

props.getSpectrum("specularReflectance",Spectrum(1.0f)));

MicrofacetDistributiondistr(props);
m_type=distr.getType();
m_sampleVisible=distr.getSampleVisible();

if(distr.isAnisotropic())

Log(EError,"The'roughplastic'plugincurrentlydoesnotsupport"

"anisotropicmicrofacetdistributions!");

m_alpha=newConstantFloatTexture(distr.getAlpha());

m_specularSamplingWeight=0.0f;

RoughCoating(Stream*stream,InstanceManager*manager)
:BSDF(stream,manager){

m_type=(MicrofacetDistribution::EType)stream>readUInt();

m_sampleVisible=stream>readBool();

m_nested=static_cast<BSDF*>(manager>getInstance(stream));

m_sigmaA=static_cast<Texture*>(manager>getInstance(stream));

m_specularReflectance=static_cast<Texture*>(manager>getInstance(stream));

m_alpha=static_cast<Texture*>(manager>getInstance(stream));

m_eta=stream>readFloat();

m_thickness=stream>readFloat();

m_invEta=1/m_eta;

voidserialize(Stream*stream,InstanceManager*manager)const{

BSDF::serialize(stream,manager);

configure();

stream>writeUInt((uint32_t)m_type);
stream>writeBool(m_sampleVisible);
manager>serialize(stream,m_nested.get());
manager>serialize(stream,m_sigmaA.get());
manager>serialize(stream,m_specularReflectance.get());
manager>serialize(stream,m_alpha.get());

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

62/84

9/12/2016

mitApi

stream>writeFloat(m_eta);
stream>writeFloat(m_thickness);

voidconfigure(){

unsignedintextraFlags=0;

if(!m_sigmaA>isConstant()||!m_alpha>isConstant())

extraFlags|=ESpatiallyVarying;

m_components.clear();
for(inti=0;i<m_nested>getComponentCount();++i)

m_components.push_back(m_nested>getType(i)|extraFlags);

m_components.push_back(EGlossyReflection|EFrontSide|EBackSide

|(m_specularReflectance>isConstant()?0:ESpatiallyVarying));

m_usesRayDifferentials=m_nested>usesRayDifferentials()

||m_sigmaA>usesRayDifferentials()

||m_alpha>usesRayDifferentials()

||m_specularReflectance>usesRayDifferentials();

/*Computeweightsthatfurthersteersamplestowards
thespecularornestedcomponents*/
FloatavgAbsorption=(m_sigmaA>getAverage()

*(2*m_thickness)).exp().average();

m_specularSamplingWeight=1.0f/(avgAbsorption+1.0f);

/*Verifytheinputparametersandfixthemifnecessary*/
m_specularReflectance=ensureEnergyConservation(

m_specularReflectance,"specularReflectance",1.0f);

if(!m_roughTransmittance.get()){

/*Loadprecomputeddatausedtocomputetherough

transmittancethroughthedielectricinterface*/

m_roughTransmittance=newRoughTransmittance(m_type);

m_roughTransmittance>checkEta(m_eta);
m_roughTransmittance>checkAlpha(m_alpha>getMinimum().average());
m_roughTransmittance>checkAlpha(m_alpha>getMaximum().average());

/*Reducetheroughtransmittancedatatoa2Dslice*/
m_roughTransmittance>setEta(m_eta);

/*Ifpossible,evenreduceittoa1Dslice*/
if(m_alpha>isConstant())

m_roughTransmittance>setAlpha(

m_alpha>eval(Intersection()).average());

BSDF::configure();

///Helperfunction:reflect\cwiwithrespecttoagivensurfacenormal
inlineVectorreflect(constVector&wi,constNormal&m)const{

return2*dot(wi,m)*Vector(m)wi;
}

///Refractioninlocalcoordinates
VectorrefractTo(EDestinationdest,constVector&wi)const{

FloatcosThetaI=Frame::cosTheta(wi);

FloatinvEta=(dest==EInterior)?m_invEta:m_eta;

boolentering=cosThetaI>0.0f;

/*UsingSnell'slaw,calculatethesquaredsineofthe
anglebetweenthenormalandthetransmittedray*/
FloatsinThetaTSqr=invEta*invEta*Frame::sinTheta2(wi);

if(sinThetaTSqr>=1.0f){

/*Totalinternalreflection*/

returnVector(0.0f);
}else{

FloatcosThetaT=std::sqrt(1.0fsinThetaTSqr);

/*Retainthedirectionalityofthevector*/
returnVector(invEta*wi.x,invEta*wi.y,

entering?cosThetaT:cosThetaT);

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

63/84

9/12/2016

mitApi

Spectrumeval(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolhasNested=(bRec.typeMask&m_nested>getType()&BSDF::EAll)

&&(bRec.component==1||bRec.component<(int)m_components.size()1);

boolhasSpecular=(bRec.typeMask&EGlossyReflection)

&&(bRec.component==1||bRec.component==(int)m_components.size()1)

&&measure==ESolidAngle;

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/
MicrofacetDistributiondistr(

m_type,

m_alpha>eval(bRec.its).average(),

m_sampleVisible
);

Spectrumresult(0.0f);
if(hasSpecular&&Frame::cosTheta(bRec.wo)*Frame::cosTheta(bRec.wi)>0){

/*Calculatethereflectionhalfvector*/

constVectorH=normalize(bRec.wo+bRec.wi)

*math::signum(Frame::cosTheta(bRec.wo));

/*Evaluatethemicrofacetnormaldistribution*/
constFloatD=distr.eval(H);

/*Fresnelterm*/
constFloatF=fresnelDielectricExt(absDot(bRec.wi,H),m_eta);

/*Smith'sshadowmaskingfunction*/
constFloatG=distr.G(bRec.wi,bRec.wo,H);

/*Calculatethespecularreflectioncomponent*/
Floatvalue=F*D*G/

(4.0f*std::abs(Frame::cosTheta(bRec.wi)));

result+=m_specularReflectance>eval(bRec.its)*value;

if(hasNested){

BSDFSamplingRecordbRecInt(bRec);

bRecInt.wi=refractTo(EInterior,bRec.wi);

bRecInt.wo=refractTo(EInterior,bRec.wo);

SpectrumnestedResult=m_nested>eval(bRecInt,measure)*

m_roughTransmittance>eval(std::abs(Frame::cosTheta(bRec.wi)),distr.getAlpha())*

m_roughTransmittance>eval(std::abs(Frame::cosTheta(bRec.wo)),distr.getAlpha());

SpectrumsigmaA=m_sigmaA>eval(bRec.its)*m_thickness;
if(!sigmaA.isZero())

nestedResult*=(sigmaA*

(1/std::abs(Frame::cosTheta(bRecInt.wi))+

1/std::abs(Frame::cosTheta(bRecInt.wo)))).exp();

/*Solidanglecompression&irradianceconversionfactors*/
if(measure==ESolidAngle)

nestedResult*=m_invEta*m_invEta*

Frame::cosTheta(bRec.wo)/Frame::cosTheta(bRecInt.wo);

result+=nestedResult;

returnresult;

Floatpdf(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolhasNested=(bRec.typeMask&m_nested>getType()&BSDF::EAll)

&&(bRec.component==1||bRec.component<(int)m_components.size()1);

boolhasSpecular=(bRec.typeMask&EGlossyReflection)

&&(bRec.component==1||bRec.component==(int)m_components.size()1)

&&measure==ESolidAngle;

/*Calculatethereflectionhalfvector*/
constVectorH=normalize(bRec.wo+bRec.wi)

*math::signum(Frame::cosTheta(bRec.wo));

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/
MicrofacetDistributiondistr(

m_type,

m_alpha>eval(bRec.its).average(),

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

64/84

9/12/2016

mitApi

);

m_sampleVisible

FloatprobNested,probSpecular;
if(hasSpecular&&hasNested){

/*Findtheprobabilityofsamplingthespecularcomponent*/

probSpecular=1m_roughTransmittance>eval(

std::abs(Frame::cosTheta(bRec.wi)),distr.getAlpha());

probNested=1probSpecular;
}else{

probNested=probSpecular=1.0f;
}

Floatresult=0.0f;
if(hasSpecular&&Frame::cosTheta(bRec.wo)*Frame::cosTheta(bRec.wi)>0){

/*Jacobianofthehalfdirectionmapping*/

constFloatdwh_dwo=1.0f/(4.0f*absDot(bRec.wo,H));

/*Evaluatethemicrofacetmodelsamplingdensityfunction*/
constFloatprob=distr.pdf(bRec.wi,H);

result=prob*dwh_dwo*probSpecular;

if(hasNested){

BSDFSamplingRecordbRecInt(bRec);

bRecInt.wi=refractTo(EInterior,bRec.wi);

bRecInt.wo=refractTo(EInterior,bRec.wo);

Floatprob=m_nested>pdf(bRecInt,measure);

if(measure==ESolidAngle){

prob*=m_invEta*m_invEta*Frame::cosTheta(bRec.wo)
/Frame::cosTheta(bRecInt.wo);
}

result+=prob*probNested;

returnresult;

inlineSpectrumsample(BSDFSamplingRecord&bRec,Float&_pdf,constPoint2&_sample)const{

boolhasNested=(bRec.typeMask&m_nested>getType()&BSDF::EAll)

&&(bRec.component==1||bRec.component<(int)m_components.size()1);

boolhasSpecular=(bRec.typeMask&EGlossyReflection)

&&(bRec.component==1||bRec.component==(int)m_components.size()1);

boolchoseSpecular=hasSpecular;
Point2sample(_sample);

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/
MicrofacetDistributiondistr(

m_type,

m_alpha>eval(bRec.its).average(),

m_sampleVisible
);

FloatprobSpecular;
if(hasSpecular&&hasNested){

/*Findtheprobabilityofsamplingthediffusecomponent*/

probSpecular=1m_roughTransmittance>eval(

std::abs(Frame::cosTheta(bRec.wi)),distr.getAlpha());

/*Reallocatesamples*/
probSpecular=(probSpecular*m_specularSamplingWeight)/

(probSpecular*m_specularSamplingWeight+

(1probSpecular)*(1m_specularSamplingWeight));

if(sample.y<probSpecular){

sample.y/=probSpecular;
}else{

sample.y=(sample.yprobSpecular)/(1probSpecular);

/*Reallocatesamples*/
probSpecular=(probSpecular*m_specularSamplingWeight)/

(probSpecular*m_specularSamplingWeight+

(1probSpecular)*(1m_specularSamplingWeight));

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

65/84

9/12/2016

mitApi

choseSpecular=false;

if(choseSpecular){

/*Perfectspecularreflectionbasedonthemicrofacetnormal*/

Normalm=distr.sample(bRec.wi,sample);

bRec.wo=reflect(bRec.wi,m);

bRec.sampledComponent=(int)m_components.size()1;

bRec.sampledType=EGlossyReflection;

bRec.eta=1.0f;

/*Sidecheck*/

if(Frame::cosTheta(bRec.wo)*Frame::cosTheta(bRec.wi)<=0)

returnSpectrum(0.0f);
}else{

Floatpdf=(Float)0;

VectorwiBackup=bRec.wi;
bRec.wi=refractTo(EInterior,bRec.wi);
Spectrumresult=m_nested>sample(bRec,pdf,sample);
bRec.wi=wiBackup;
if(pdf<=(Float)0)

returnSpectrum(0.0f);
bRec.wo=refractTo(EExterior,bRec.wo);

if(bRec.wo.isZero())

returnSpectrum(0.0f);

/*Guardagainstnumericalimprecisions*/
EMeasuremeasure=getMeasure(bRec.sampledType);
_pdf=pdf(bRec,measure);

if(_pdf==0)

returnSpectrum(0.0f);
else

returneval(bRec,measure)/_pdf;

Spectrumsample(BSDFSamplingRecord&bRec,constPoint2&sample)const{

Floatpdf;

returnRoughCoating::sample(bRec,pdf,sample);
}

FloatgetRoughness(constIntersection&its,intcomponent)const{

returncomponent<(int)m_components.size()1

?m_nested>getRoughness(its,component)

:m_alpha>eval(its).average();
}

voidaddChild(conststd::string&name,ConfigurableObject*child){

if(child>getClass()>derivesFrom(MTS_CLASS(BSDF))){

if(m_nested!=NULL)

Log(EError,"OnlyasinglenestedBRDFcanbeadded!");

m_nested=static_cast<BSDF*>(child);

}elseif(child>getClass()>derivesFrom(MTS_CLASS(Texture))){

if(name=="sigmaA")

m_sigmaA=static_cast<Texture*>(child);

elseif(name=="alpha")

m_alpha=static_cast<Texture*>(child);

else

BSDF::addChild(name,child);

}else{

BSDF::addChild(name,child);

}
}

std::stringtoString()const{

std::ostringstreamoss;

oss<<"RoughCoating["<<endl

<<"id=\""<<getID()<<"\","<<endl

<<"distribution="<<MicrofacetDistribution::distributionName(m_type)<<","<<endl

<<"sampleVisible="<<m_sampleVisible<<","<<endl

<<"alpha="<<indent(m_alpha>toString())<<","<<endl

<<"sigmaA="<<indent(m_sigmaA>toString())<<","<<endl

<<"specularReflectance="<<indent(m_specularReflectance>toString())<<","<<endl

<<"specularSamplingWeight="<<m_specularSamplingWeight<<","<<endl

<<"diffuseSamplingWeight="<<(1m_specularSamplingWeight)<<","<<endl

<<"eta="<<m_eta<<","<<endl

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

66/84

9/12/2016

mitApi

<<"nested="<<indent(m_nested.toString())<<endl

<<"]";
returnoss.str();

Shader*createShader(Renderer*renderer)const;

MTS_DECLARE_CLASS()
private:

MicrofacetDistribution::ETypem_type;

ref<RoughTransmittance>m_roughTransmittance;

ref<Texture>m_sigmaA;

ref<Texture>m_alpha;

ref<Texture>m_specularReflectance;

ref<BSDF>m_nested;

Floatm_eta,m_invEta;

Floatm_specularSamplingWeight;

Floatm_thickness;

boolm_sampleVisible;
};
/**
*GLSLportoftheroughcoatingshader.Thisversionismuchmore
*approximateitonlysupportstheBeckmanndistribution,
*doeseverythinginRGB,usesacheapershadowingmaskingterm,and
*italsomakesuseoftheSchlickapproximationtotheFresnel
*reflectanceofdielectrics.Whentheroughnessislowerthan
*\alpha<0.2,theshaderclampsitto0.2sothatitwillstillperform
*reasonablywellinaVPLbasedpreview.
*/
classRoughCoatingShader:publicShader{
public:

RoughCoatingShader(Renderer*renderer,constBSDF*nested,

constTexture*sigmaA,constTexture*alpha,

Floateta):Shader(renderer,EBSDFShader),

m_nested(nested),m_sigmaA(sigmaA),m_alpha(alpha),m_eta(eta){

m_nestedShader=renderer>registerShaderForResource(m_nested.get());

m_sigmaAShader=renderer>registerShaderForResource(m_sigmaA.get());

m_alphaShader=renderer>registerShaderForResource(m_alpha.get());

m_R0=fresnelDielectricExt(1.0f,eta);

boolisComplete()const{

returnm_nestedShader.get()!=NULL

&&m_sigmaAShader.get()!=NULL

&&m_alphaShader.get()!=NULL;
}

voidputDependencies(std::vector<Shader*>&deps){

deps.push_back(m_nestedShader.get());

deps.push_back(m_sigmaAShader.get());

deps.push_back(m_alphaShader.get());
}

voidcleanup(Renderer*renderer){

renderer>unregisterShaderForResource(m_nested.get());

renderer>unregisterShaderForResource(m_sigmaA.get());

renderer>unregisterShaderForResource(m_alpha.get());
}

voidresolve(constGPUProgram*program,conststd::string&evalName,std::vector<int>&parameterIDs)const

voidbind(GPUProgram*program,conststd::vector<int>&parameterIDs,int&textureUnitOffset)const{

program>setParameter(parameterIDs[0],m_R0);

program>setParameter(parameterIDs[1],m_eta);
}

voidgenerateCode(std::ostringstream&oss,

conststd::string&evalName,

conststd::vector<std::string>&depNames)const{

oss<<"uniformfloat"<<evalName<<"_R0;"<<endl

<<"uniformfloat"<<evalName<<"_eta;"<<endl

<<endl

<<"float"<<evalName<<"_schlick(floatct){"<<endl

<<"floatctSqr=ct*ct,ct5=ctSqr*ctSqr*ct;"<<endl

<<"return"<<evalName<<"_R0+(1.0"<<evalName<<"_R0)*ct5;"<<endl

parameterIDs.push_back(program>getParameterID(evalName+"_R0",false));
parameterIDs.push_back(program>getParameterID(evalName+"_eta",false));

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

67/84

9/12/2016

endl

mitApi

<<"}"<<endl
<<endl
<<"vec3"<<evalName<<"_refract(vec3wi,outfloatT){"<<endl
<<"floatcosThetaI=cosTheta(wi);"<<endl
<<"boolentering=cosThetaI>0.0;"<<endl
<<"floatinvEta=1.0/"<<evalName<<"_eta;"<<endl
<<"floatsinThetaTSqr=invEta*invEta*sinTheta2(wi);"<<endl
<<"if(sinThetaTSqr>=1.0){"<<endl
<<"T=0.0;/*Totalinternalreflection*/"<<endl
<<"returnvec3(0.0);"<<endl
<<"}else{"<<endl
<<"floatcosThetaT=sqrt(1.0sinThetaTSqr);"<<endl
<<"T=1.0"<<evalName<<"_schlick(1.0abs(cosThetaI));"<<endl
<<"returnvec3(invEta*wi.x,invEta*wi.y,entering?cosThetaT:cosThetaT);"<<

<<"}"<<endl
<<"}"<<endl
<<endl
<<"float"<<evalName<<"_D(vec3m,floatalpha){"<<endl
<<"floatct=cosTheta(m);"<<endl
<<"if(cosTheta(m)<=0.0)"<<endl
<<"return0.0;"<<endl
<<"floatex=tanTheta(m)/alpha;"<<endl
<<"returnexp((ex*ex))/(pi*alpha*alpha*"<<endl
<<"pow(cosTheta(m),4.0));"<<endl
<<"}"<<endl
<<endl
<<"float"<<evalName<<"_G(vec3m,vec3wi,vec3wo){"<<endl
<<"if((dot(wi,m)*cosTheta(wi))<=0||"<<endl
<<"(dot(wo,m)*cosTheta(wo))<=0)"<<endl
<<"return0.0;"<<endl
<<"floatnDotM=cosTheta(m);"<<endl
<<"returnmin(1.0,min("<<endl
<<"abs(2*nDotM*cosTheta(wo)/dot(wo,m)),"<<endl
<<"abs(2*nDotM*cosTheta(wi)/dot(wi,m))));"<<endl
<<"}"<<endl
<<endl
<<"vec3"<<evalName<<"(vec2uv,vec3wi,vec3wo){"<<endl
<<"floatT12,T21;"<<endl
<<"vec3wiPrime="<<evalName<<"_refract(wi,T12);"<<endl
<<"vec3woPrime="<<evalName<<"_refract(wo,T21);"<<endl
<<"vec3nested="<<depNames[0]<<"(uv,wiPrime,woPrime);"<<endl
<<"vec3sigmaA="<<depNames[1]<<"(uv);"<<endl
<<"vec3result=nested*"<<evalName<<"_eta*"<<evalName<<"_eta"<<endl
<<"*T12*T21*(cosTheta(wi)*cosTheta(wo))/"<<endl
<<"(cosTheta(wiPrime)*cosTheta(woPrime));"<<endl
<<"if(sigmaA!=vec3(0.0))"<<endl
<<"result*=exp(sigmaA*(1/abs(cosTheta(wiPrime))+"<<endl
<<"1/abs(cosTheta(woPrime))));"<<endl
<<"if(cosTheta(wi)*cosTheta(wo)>0){"<<endl
<<"vec3H=normalize(wi+wo);"<<endl
<<"floatalpha=max(0.2,"<<depNames[2]<<"(uv)[0]);"<<endl
<<"floatD="<<evalName<<"_D(H,alpha)"<<";"<<endl
<<"floatG="<<evalName<<"_G(H,wi,wo);"<<endl
<<"floatF="<<evalName<<"_schlick(1dot(wi,H));"<<endl
<<"result+=vec3(F*D*G/(4*cosTheta(wi)));"<<endl
<<"}"<<endl
<<"returnresult;"<<endl
<<"}"<<endl
<<endl
<<"vec3"<<evalName<<"_diffuse(vec2uv,vec3wi,vec3wo){"<<endl
<<"return"<<depNames[0]<<"_diffuse(uv,wi,wo);"<<endl
<<"}"<<endl;

MTS_DECLARE_CLASS()
private:

ref<constBSDF>m_nested;

ref<Shader>m_nestedShader;

ref<constTexture>m_sigmaA;

ref<Shader>m_sigmaAShader;

ref<constTexture>m_alpha;

ref<Shader>m_alphaShader;

Floatm_R0,m_eta;
};
Shader*RoughCoating::createShader(Renderer*renderer)const{

returnnewRoughCoatingShader(renderer,m_nested.get(),

m_sigmaA.get(),m_alpha.get(),m_eta);
}
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

68/84

9/12/2016

mitApi

MTS_IMPLEMENT_CLASS(RoughCoatingShader,false,Shader)
MTS_IMPLEMENT_CLASS_S(RoughCoating,false,BSDF)
MTS_EXPORT_PLUGIN(RoughCoating,"RoughcoatingBSDF");
MTS_NAMESPACE_END

https://raw.githubusercontent.com/mmanzi/gradientdomain
mitsuba/7f01a2c044440c774dd88afe05eea4acdc418f2c/src/bsdfs/roughplastic.cpp

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

69/84

9/12/2016

mitApi

#include<mitsuba/render/bsdf.h>
#include<mitsuba/hw/basicshader.h>
#include<mitsuba/core/warp.h>
#include"microfacet.h"
#include"rtrans.h"
#include"ior.h"
MTS_NAMESPACE_BEGIN
/*!\plugin{roughplastic}{Roughplasticmaterial}
*\order{9}
*\icon{bsdf_roughplastic}
*\parameters{
*\parameter{distribution}{\String}{
*Specifiesthetypeofmicrofacetnormaldistribution
*usedtomodelthesurfaceroughness.
*\vspace{1mm}
*\begin{enumerate}[(i)]
*\item\code{beckmann}:Physicallybaseddistributionderivedfrom
*Gaussianrandomsurfaces.Thisisthedefault.\vspace{1.5mm}
*\item\code{ggx}:TheGGX\cite{Walter07Microfacet}distribution(alsoknownas
*TrowbridgeReitz\cite{Trowbridge19975Average}distribution)
*wasdesignedtobetterapproximatethelongtailsobservedinmeasurements
*ofgroundsurfaces,whicharenotmodeledbytheBeckmanndistribution.
*\vspace{1.5mm}
*\item\code{phong}:ClassicalPhongdistribution.
*Inmostcases,the\code{ggx}and\code{beckmann}distributions
*shouldbepreferred,sincetheyprovidebetterimportancesampling
*andaccurateshadowing/maskingcomputations.
*\vspace{4mm}
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

70/84

9/12/2016

mitApi

*\end{enumerate}
*}
*\parameter{alpha}{\Float\Or\Texture}{
*Specifiestheroughnessoftheunresolvedsurfacemicrogeometry.
*WhentheBeckmanndistributionisused,thisparameterisequaltothe
*\emph{rootmeansquare}(RMS)slopeofthemicrofacets.
*\default{0.1}.
*}
*
*\parameter{intIOR}{\Float\Or\String}{Interiorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{polypropylene}/1.49}}
*\parameter{extIOR}{\Float\Or\String}{Exteriorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{air}/1.000277}}
*\parameter{sampleVisible}{\Boolean}{
*
Enablesanimprovedimportancesamplingtechnique.Referto
*
pages\pageref{plg:roughconductor}and\pageref{sec:visiblenormalsampling}
*
fordetails.\default{\code{true}}
*}
*\parameter{specular\showbreakReflectance}{\Spectrum\Or\Texture}{Optional
*factorthatcanbeusedtomodulatethespecularreflectioncomponent.Note
*thatforphysicalrealism,thisparametershouldneverbetouched.\default{1.0}}
*\parameter{diffuse\showbreakReflectance}{\Spectrum\Or\Texture}{Optional
*factorusedtomodulatethediffusereflectioncomponent\default{0.5}}
*\parameter{nonlinear}{\Boolean}{
*Accountfornonlinearcolorshiftsduetointernalscattering?Seethe
*\pluginref{plastic}pluginfordetails.\default{Don'taccountforthemand
*preservethetexturecolors,i.e.\code{false}}
*}
*}
*
*\vspace{3mm}
*Thispluginimplementsarealisticmicrofacetscatteringmodelforrendering
*roughdielectricmaterialswithinternalscattering,suchasplastic.Itcan
*beinterpretedasafancyversionoftheCookTorrancemodelandshouldbe
*preferredoverheuristicmodelslike\pluginref{phong}and\pluginref{ward}
*whenpossible.
*
*Microfacettheorydescribesroughsurfacesasanarrangementof
*unresolvedandideallyspecularfacets,whosenormaldirectionsaregivenby
*aspeciallychosen\emph{microfacetdistribution}.Byaccountingforshadowing
*andmaskingeffectsbetweenthesefacets,itispossibletoreproducetheimportant
*offspecularreflectionspeaksobservedinrealworldmeasurementsofsuch
*materials.
*
*\renderings{
*\rendering{Beckmann,$\alpha=0.1$}{bsdf_roughplastic_beckmann}
*\rendering{GGX,$\alpha=0.3$}{bsdf_roughplastic_ggx}
*}
*
*Thispluginisessentiallythe``roughened''equivalentofthe(smooth)plugin
*\pluginref{plastic}.Forverylowvaluesof$\alpha$,thetwowill
*beidentical,thoughscenesusingthispluginwilltakelongertorender
*duetotheadditionalcomputationalburdenoftrackingsurfaceroughness.
*
*Forconvenience,thismodelallowstospecifyIORvalueseithernumerically,
*orbasedonalistofknownmaterials(see\tblref{dielectriciors}on
*\tblpage{dielectriciors}foranoverview).
*Whennoparametersaregiven,thepluginactivatesthedefaults,
*whichdescribeawhitepolypropyleneplasticmaterialwithalightamount
*ofroughnessmodeledusingtheBeckmanndistribution.
*
*Likethe\pluginref{plastic}material,thismodelinternallysimulatesthe
*interactionoflightwithadiffusebasesurfacecoatedbyathindielectric
*layer(wherethecoatinglayerisnow\emph{rough}).Thisisaconvenient
*abstractionratherthanarestriction.Inotherwords,therearemany
*materialsthatcanberenderedwiththismodel,eveniftheymightnot
*fitthisdescriptionperfectlywell.
*
*Thesimplicityofthissetupmakesitpossibletoaccountforinteresting
*nonlineareffectsduetointernalscattering,whichiscontrolledby
*the\texttt{nonlinear}parameter.Formoredetails,pleaserefertothedescription
*ofthisparametergiveninthe\pluginref{plastic}pluginsection
*on\pluginpage{plastic}.
*
*Togetanintuitionabouttheeffectofthesurfaceroughnessparameter
*$\alpha$,considerthefollowingapproximateclassification:avalueof
*$\alpha=0.0010.01$correspondstoamaterialwithslightimperfections
*onanotherwisesmoothsurfacefinish,$\alpha=0.1$isrelativelyrough,
*and$\alpha=0.30.7$is\emph{extremely}rough(e.g.anetchedorground
*finish).Valuessignificantlyabovethatareprobablynottoorealistic.
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

71/84

9/12/2016

mitApi

*
*\renderings{
*\medrendering{Diffusetexturedrendering}{bsdf_plastic_diffuse}
*\medrendering{Texturedroughplasticmodeland\code{nonlinear=false}}{bsdf_roughplastic_preserve}
*\medrendering{Texturedroughplasticmodeland\code{nonlinear=true}}{bsdf_roughplastic_nopreserve}
*\caption{
*Whenaskedtodoso,thismodelcanaccountforsubtlenonlinearcolorshiftsdue
*tointernalscatteringprocesses.Theaboveimagesshowatextured
*objectfirstrenderedusing\pluginref{diffuse},then
*\pluginref{roughplastic}withthedefaultparameters,andfinallyusing
*\pluginref{roughplastic}andsupportfornonlinearcolorshifts.
*}
*}
*\renderings{
*\rendering{Woodmaterialwithsmoothhorizontalstripes}{bsdf_roughplastic_roughtex1}
*\rendering{Amaterialwithimperfectionsatamuchsmallerscalethanwhat
*ismodelede.g.usingabumpmap.}{bsdf_roughplastic_roughtex2}\vspace{3mm}
*\caption{
*Theabilitytotexturetheroughnessparametermakesitpossible
*torendermaterialswithastructuredfinish,aswellas
*``smudgy''objects.
*}
*}
*\vspace{2mm}
*\begin{xml}[caption={Amaterialdefinitionforblackplasticmaterialwith
*aspatiallyvaryingroughness.},
*label=lst:roughplasticvaryingalpha]
*<bsdftype="roughplastic">
*<stringname="distribution"value="beckmann"/>
*<floatname="intIOR"value="1.61"/>
*<spectrumname="diffuseReflectance"value="0"/>
*<!Fetchroughnessvaluesfromatextureandslightlyreducethem>
*<texturetype="scale"name="alpha">
*<texturename="alpha"type="bitmap">
*<stringname="filename"value="roughness.png"/>
*</texture>
*<floatname="scale"value="0.6"/>
*</texture>
*</bsdf>
*\end{xml}
*
*\subsubsection*{Technicaldetails}
*Theimplementationofthismodelispartlybasedonthepaper``Microfacet
*ModelsforRefractionthroughRoughSurfaces''byWalteretal.
*\cite{Walter07Microfacet}.Severaldifferenttypesofmicrofacet
*distributionsaresupported.Notethatthechoicesareslightlymore
*restrictedhereincomparisontootherroughscatteringmodelsin
*Mitsuba,anisotropicdistributionsarenotallowed.
*
*Theimplementationofthismodelmakesheavyuseofa\emph{rough
*Fresneltransmittance}function,whichisageneralizationofthe
*usualFresneltransmittioncoefficienttomicrofacetsurfaces.Unfortunately,
*thisfunctionisnormallyprohibitivelyexpensive,sinceeach
*evaluationinvolvesanumericalintegrationoverthesphere.
*
*Toavoidthisperformanceissue,Mitsubashipswithdatafiles
*(containedinthe\code{data/microfacet}directory)containingprecomputed
*valuesofthisfunctionoveralargerangeofparametervalues.Atruntime,
*therelevantpartsareextractedusingtricubicinterpolation.
*
*WhenrenderingwiththePhongmicrofacetdistribution,aconversionis
*usedtoturnthespecifiedBeckmannequivalent$\alpha$roughnessvalue
*intotheexponentparameterofthisdistribution.Thisisdoneinaway,
*suchthatthesamevalue$\alpha$willproduceasimilarappearanceacross
*differentmicrofacetdistributions.
*/
classRoughPlastic:publicBSDF{
public:

RoughPlastic(constProperties&props):BSDF(props){

m_specularReflectance=newConstantSpectrumTexture(

props.getSpectrum("specularReflectance",Spectrum(1.0f)));

m_diffuseReflectance=newConstantSpectrumTexture(

props.getSpectrum("diffuseReflectance",Spectrum(0.5f)));

/*Specifiestheinternalindexofrefractionattheinterface*/
FloatintIOR=lookupIOR(props,"intIOR","polypropylene");

/*Specifiestheexternalindexofrefractionattheinterface*/
FloatextIOR=lookupIOR(props,"extIOR","air");

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

72/84

9/12/2016

mitApi

if(intIOR<0||extIOR<0||intIOR==extIOR)

Log(EError,"Theinteriorandexteriorindicesof"

"refractionmustbepositiveanddiffer!");

m_eta=intIOR/extIOR;

m_nonlinear=props.getBoolean("nonlinear",false);

MicrofacetDistributiondistr(props);
m_type=distr.getType();
m_sampleVisible=distr.getSampleVisible();

if(distr.isAnisotropic())

Log(EError,"The'roughplastic'plugincurrentlydoesnotsupport"

"anisotropicmicrofacetdistributions!");

m_alpha=newConstantFloatTexture(distr.getAlpha());

m_specularSamplingWeight=0.0f;

RoughPlastic(Stream*stream,InstanceManager*manager)
:BSDF(stream,manager){

m_type=(MicrofacetDistribution::EType)stream>readUInt();

m_sampleVisible=stream>readBool();

m_specularReflectance=static_cast<Texture*>(manager>getInstance(stream));

m_diffuseReflectance=static_cast<Texture*>(manager>getInstance(stream));

m_alpha=static_cast<Texture*>(manager>getInstance(stream));

m_eta=stream>readFloat();

m_nonlinear=stream>readBool();

voidserialize(Stream*stream,InstanceManager*manager)const{

BSDF::serialize(stream,manager);

voidconfigure(){

boolconstAlpha=m_alpha>isConstant();

m_components.clear();

m_components.push_back(EGlossyReflection|EFrontSide

|((constAlpha&&m_specularReflectance>isConstant())

?0:ESpatiallyVarying));
m_components.push_back(EDiffuseReflection|EFrontSide

|((constAlpha&&m_diffuseReflectance>isConstant())

?0:ESpatiallyVarying));

/*Verifytheinputparametersandfixthemifnecessary*/
m_specularReflectance=ensureEnergyConservation(

m_specularReflectance,"specularReflectance",1.0f);
m_diffuseReflectance=ensureEnergyConservation(

m_diffuseReflectance,"diffuseReflectance",1.0f);

/*Computeweightsthatfurthersteersamplestowards
thespecularordiffusecomponents*/
FloatdAvg=m_diffuseReflectance>getAverage().getLuminance(),

sAvg=m_specularReflectance>getAverage().getLuminance();
m_specularSamplingWeight=sAvg/(dAvg+sAvg);

m_invEta2=1.0f/(m_eta*m_eta);

if(!m_externalRoughTransmittance.get()){

/*Loadprecomputeddatausedtocomputetherough

transmittancethroughthedielectricinterface*/

m_externalRoughTransmittance=newRoughTransmittance(m_type);

configure();

stream>writeUInt((uint32_t)m_type);
stream>writeBool(m_sampleVisible);
manager>serialize(stream,m_specularReflectance.get());
manager>serialize(stream,m_diffuseReflectance.get());
manager>serialize(stream,m_alpha.get());
stream>writeFloat(m_eta);
stream>writeBool(m_nonlinear);

m_externalRoughTransmittance>checkEta(m_eta);
m_externalRoughTransmittance>checkAlpha(m_alpha>getMinimum().average());
m_externalRoughTransmittance>checkAlpha(m_alpha>getMaximum().average());

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

73/84

9/12/2016

mitApi

/*Reducetheroughtransmittancedatatoa2Dslice*/
m_internalRoughTransmittance=m_externalRoughTransmittance>clone();
m_externalRoughTransmittance>setEta(m_eta);
m_internalRoughTransmittance>setEta(1/m_eta);

/*Ifpossible,evenreduceittoa1Dslice*/
if(constAlpha)

m_externalRoughTransmittance>setAlpha(

m_alpha>eval(Intersection()).average());

m_usesRayDifferentials=

m_specularReflectance>usesRayDifferentials()||

m_diffuseReflectance>usesRayDifferentials()||

m_alpha>usesRayDifferentials();

BSDF::configure();

SpectrumgetDiffuseReflectance(constIntersection&its)const{

/*Evaluatetheroughnesstexture*/

Floatalpha=m_alpha>eval(its).average();

FloatFtr=m_externalRoughTransmittance>evalDiffuse(alpha);

SpectrumgetSpecularReflectance(constIntersection&its)const{

returnm_specularReflectance>eval(its);
}

///Helperfunction:reflect\cwiwithrespecttoagivensurfacenormal
inlineVectorreflect(constVector&wi,constNormal&m)const{

return2*dot(wi,m)*Vector(m)wi;
}

Spectrumeval(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolhasSpecular=(bRec.typeMask&EGlossyReflection)&&

(bRec.component==1||bRec.component==0);

boolhasDiffuse=(bRec.typeMask&EDiffuseReflection)&&

(bRec.component==1||bRec.component==1);

if(measure!=ESolidAngle||

Frame::cosTheta(bRec.wi)<=0||

Frame::cosTheta(bRec.wo)<=0||

(!hasSpecular&&!hasDiffuse))

returnSpectrum(0.0f);

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/
MicrofacetDistributiondistr(

m_type,

m_alpha>eval(bRec.its).average(),

m_sampleVisible
);

Spectrumresult(0.0f);
if(hasSpecular){

/*Calculatethereflectionhalfvector*/

constVectorH=normalize(bRec.wo+bRec.wi);

/*Evaluatethemicrofacetnormaldistribution*/
constFloatD=distr.eval(H);

/*Fresnelterm*/
constFloatF=fresnelDielectricExt(dot(bRec.wi,H),m_eta);

/*Smith'sshadowmaskingfunction*/
constFloatG=distr.G(bRec.wi,bRec.wo,H);

/*Calculatethespecularreflectioncomponent*/
Floatvalue=F*D*G/

(4.0f*Frame::cosTheta(bRec.wi));

result+=m_specularReflectance>eval(bRec.its)*value;

if(hasDiffuse){

Spectrumdiff=m_diffuseReflectance>eval(bRec.its);

returnm_diffuseReflectance>eval(its)*Ftr;

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

74/84

9/12/2016

mitApi

FloatT12=m_externalRoughTransmittance>eval(Frame::cosTheta(bRec.wi),distr.getAlpha());
FloatT21=m_externalRoughTransmittance>eval(Frame::cosTheta(bRec.wo),distr.getAlpha());
FloatFdr=1m_internalRoughTransmittance>evalDiffuse(distr.getAlpha());

if(m_nonlinear)

diff/=Spectrum(1.0f)diff*Fdr;
else

diff/=1Fdr;

result+=diff*(INV_PI*Frame::cosTheta(bRec.wo)*T12*T21*m_invEta2);

returnresult;

Floatpdf(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolhasSpecular=(bRec.typeMask&EGlossyReflection)&&

(bRec.component==1||bRec.component==0);

boolhasDiffuse=(bRec.typeMask&EDiffuseReflection)&&

(bRec.component==1||bRec.component==1);

if(measure!=ESolidAngle||

Frame::cosTheta(bRec.wi)<=0||

Frame::cosTheta(bRec.wo)<=0||

(!hasSpecular&&!hasDiffuse))

return0.0f;

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/
MicrofacetDistributiondistr(

m_type,

m_alpha>eval(bRec.its).average(),

m_sampleVisible
);

/*Calculatethereflectionhalfvector*/
constVectorH=normalize(bRec.wo+bRec.wi);

FloatprobDiffuse,probSpecular;

if(hasSpecular&&hasDiffuse){

/*Findtheprobabilityofsamplingthespecularcomponent*/

probSpecular=1m_externalRoughTransmittance>eval(Frame::cosTheta(bRec.wi),
distr.getAlpha());

/*Reallocatesamples*/
probSpecular=(probSpecular*m_specularSamplingWeight)/

(probSpecular*m_specularSamplingWeight+

(1probSpecular)*(1m_specularSamplingWeight));

probDiffuse=1probSpecular;
}else{

probDiffuse=probSpecular=1.0f;
}

Floatresult=0.0f;
if(hasSpecular){

/*Jacobianofthehalfdirectionmapping*/

constFloatdwh_dwo=1.0f/(4.0f*dot(bRec.wo,H));

/*Evaluatethemicrofacetmodelsamplingdensityfunction*/
constFloatprob=distr.pdf(bRec.wi,H);

result=prob*dwh_dwo*probSpecular;

if(hasDiffuse)

result+=probDiffuse*warp::squareToCosineHemispherePdf(bRec.wo);

returnresult;

inlineSpectrumsample(BSDFSamplingRecord&bRec,Float&_pdf,constPoint2&_sample)const{

boolhasSpecular=(bRec.typeMask&EGlossyReflection)&&

(bRec.component==1||bRec.component==0);

boolhasDiffuse=(bRec.typeMask&EDiffuseReflection)&&

(bRec.component==1||bRec.component==1);

if(Frame::cosTheta(bRec.wi)<=0||(!hasSpecular&&!hasDiffuse))

returnSpectrum(0.0f);

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

75/84

9/12/2016

mitApi

boolchoseSpecular=hasSpecular;
Point2sample(_sample);

/*Constructthemicrofacetdistributionmatchingthe
roughnessvaluesatthecurrentsurfaceposition.*/
MicrofacetDistributiondistr(

m_type,

m_alpha>eval(bRec.its).average(),

m_sampleVisible
);

FloatprobSpecular;

if(hasSpecular&&hasDiffuse){

/*Findtheprobabilityofsamplingthespecularcomponent*/

probSpecular=1m_externalRoughTransmittance>eval(Frame::cosTheta(bRec.wi),
distr.getAlpha());

/*Reallocatesamples*/
probSpecular=(probSpecular*m_specularSamplingWeight)/

(probSpecular*m_specularSamplingWeight+

(1probSpecular)*(1m_specularSamplingWeight));

if(sample.y<probSpecular){

sample.y/=probSpecular;
}else{

sample.y=(sample.yprobSpecular)/(1probSpecular);

choseSpecular=false;
}

if(choseSpecular){

/*Perfectspecularreflectionbasedonthemicrofacetnormal*/

Normalm=distr.sample(bRec.wi,sample);

bRec.wo=reflect(bRec.wi,m);

bRec.sampledComponent=0;

bRec.sampledType=EGlossyReflection;

/*Sidecheck*/

if(Frame::cosTheta(bRec.wo)<=0)

returnSpectrum(0.0f);
}else{

bRec.sampledComponent=1;

bRec.sampledType=EDiffuseReflection;

bRec.wo=warp::squareToCosineHemisphere(sample);
}
bRec.eta=1.0f;

/*Guardagainstnumericalimprecisions*/
_pdf=pdf(bRec,ESolidAngle);

if(_pdf==0)

returnSpectrum(0.0f);
else

returneval(bRec,ESolidAngle)/_pdf;

Spectrumsample(BSDFSamplingRecord&bRec,constPoint2&sample)const{

Floatpdf;

returnRoughPlastic::sample(bRec,pdf,sample);
}

voidaddChild(conststd::string&name,ConfigurableObject*child){

if(child>getClass()>derivesFrom(MTS_CLASS(Texture))){

if(name=="alpha")

m_alpha=static_cast<Texture*>(child);

elseif(name=="specularReflectance")

m_specularReflectance=static_cast<Texture*>(child);

elseif(name=="diffuseReflectance")

m_diffuseReflectance=static_cast<Texture*>(child);

else

BSDF::addChild(name,child);

}else{

BSDF::addChild(name,child);

}
}

FloatgetRoughness(constIntersection&its,intcomponent)const{

Assert(component==0||component==1);

if(component==0)

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

76/84

9/12/2016

mitApi

else

returnm_alpha>eval(its).average();

std::stringtoString()const{

std::ostringstreamoss;

oss<<"RoughPlastic["<<endl

<<"id=\""<<getID()<<"\","<<endl

<<"distribution="<<MicrofacetDistribution::distributionName(m_type)<<","<<endl

<<"sampleVisible="<<m_sampleVisible<<","<<endl

<<"alpha="<<indent(m_alpha>toString())<<","<<endl

<<"specularReflectance="<<indent(m_specularReflectance>toString())<<","<<endl

<<"diffuseReflectance="<<indent(m_diffuseReflectance>toString())<<","<<endl

<<"specularSamplingWeight="<<m_specularSamplingWeight<<","<<endl

<<"diffuseSamplingWeight="<<(1m_specularSamplingWeight)<<","<<endl

<<"eta="<<m_eta<<","<<endl

<<"nonlinear="<<m_nonlinear<<endl

<<"]";

returnoss.str();
}

Shader*createShader(Renderer*renderer)const;

returnstd::numeric_limits<Float>::infinity();

MTS_DECLARE_CLASS()
private:

MicrofacetDistribution::ETypem_type;

ref<RoughTransmittance>m_externalRoughTransmittance;

ref<RoughTransmittance>m_internalRoughTransmittance;

ref<Texture>m_diffuseReflectance;

ref<Texture>m_specularReflectance;

ref<Texture>m_alpha;

Floatm_eta,m_invEta2;

Floatm_specularSamplingWeight;

boolm_nonlinear;

boolm_sampleVisible;
};
/**
*GLSLportoftheroughplasticshader.Thisversionismuchmore
*approximateitonlysupportstheBeckmanndistribution,
*doeseverythinginRGB,usesacheapershadowingmaskingterm,and
*italsomakesuseoftheSchlickapproximationtotheFresnel
*reflectanceofdielectrics.Whentheroughnessislowerthan
*\alpha<0.2,theshaderclampsitto0.2sothatitwillstillperform
*reasonablywellinaVPLbasedpreview.Thereisnosupportfor
*nonlineareffectsduetointernalscattering.
*/
classRoughPlasticShader:publicShader{
public:

RoughPlasticShader(Renderer*renderer,constTexture*specularReflectance,

constTexture*diffuseReflectance,constTexture*alpha,Floateta)

:Shader(renderer,EBSDFShader),

m_specularReflectance(specularReflectance),

m_diffuseReflectance(diffuseReflectance),

m_alpha(alpha){

m_specularReflectanceShader=renderer>registerShaderForResource(m_specularReflectance.get());

m_diffuseReflectanceShader=renderer>registerShaderForResource(m_diffuseReflectance.get());

m_alphaShader=renderer>registerShaderForResource(m_alpha.get());

m_R0=fresnelDielectricExt(1.0f,eta);

boolisComplete()const{

returnm_specularReflectanceShader.get()!=NULL&&

m_diffuseReflectanceShader.get()!=NULL&&

m_alphaShader.get()!=NULL;
}

voidputDependencies(std::vector<Shader*>&deps){

deps.push_back(m_specularReflectanceShader.get());

deps.push_back(m_diffuseReflectanceShader.get());

deps.push_back(m_alphaShader.get());
}

voidcleanup(Renderer*renderer){

renderer>unregisterShaderForResource(m_specularReflectance.get());

renderer>unregisterShaderForResource(m_diffuseReflectance.get());

renderer>unregisterShaderForResource(m_alpha.get());
}

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

77/84

9/12/2016

mitApi

voidresolve(constGPUProgram*program,conststd::string&evalName,std::vector<int>&parameterIDs)const

voidbind(GPUProgram*program,conststd::vector<int>&parameterIDs,int&textureUnitOffset)const{

program>setParameter(parameterIDs[0],m_R0);
}

parameterIDs.push_back(program>getParameterID(evalName+"_R0",false));

voidgenerateCode(std::ostringstream&oss,

conststd::string&evalName,

conststd::vector<std::string>&depNames)const{

oss<<"uniformfloat"<<evalName<<"_R0;"<<endl

<<endl

<<"float"<<evalName<<"_D(vec3m,floatalpha){"<<endl

<<"floatct=cosTheta(m);"<<endl

<<"if(cosTheta(m)<=0.0)"<<endl

<<"return0.0;"<<endl

<<"floatex=tanTheta(m)/alpha;"<<endl

<<"returnexp((ex*ex))/(pi*alpha*alpha*"<<endl

<<"pow(cosTheta(m),4.0));"<<endl

<<"}"<<endl

<<endl

<<"float"<<evalName<<"_G(vec3m,vec3wi,vec3wo){"<<endl

<<"if((dot(wi,m)*cosTheta(wi))<=0||"<<endl

<<"(dot(wo,m)*cosTheta(wo))<=0)"<<endl

<<"return0.0;"<<endl

<<"floatnDotM=cosTheta(m);"<<endl

<<"returnmin(1.0,min("<<endl

<<"abs(2*nDotM*cosTheta(wo)/dot(wo,m)),"<<endl

<<"abs(2*nDotM*cosTheta(wi)/dot(wi,m))));"<<endl

<<"}"<<endl

<<endl

<<endl

<<"float"<<evalName<<"_schlick(floatct){"<<endl

<<"floatctSqr=ct*ct,ct5=ctSqr*ctSqr*ct;"<<endl

<<"return"<<evalName<<"_R0+(1.0"<<evalName<<"_R0)*ct5;"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"(vec2uv,vec3wi,vec3wo){"<<endl

<<"if(cosTheta(wi)<=0||cosTheta(wo)<=0)"<<endl

<<"returnvec3(0.0);"<<endl

<<"vec3H=normalize(wi+wo);"<<endl

<<"vec3specRef="<<depNames[0]<<"(uv);"<<endl

<<"vec3diffuseRef="<<depNames[1]<<"(uv);"<<endl

<<"floatalpha=max(0.2,"<<depNames[2]<<"(uv)[0]);"<<endl

<<"floatD="<<evalName<<"_D(H,alpha)"<<";"<<endl

<<"floatG="<<evalName<<"_G(H,wi,wo);"<<endl

<<"floatF="<<evalName<<"_schlick(1dot(wi,H));"<<endl

<<"returnspecRef*(F*D*G/(4*cosTheta(wi)))+"<<endl

<<"diffuseRef*((1F)*cosTheta(wo)*inv_pi);"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"_diffuse(vec2uv,vec3wi,vec3wo){"<<endl

<<"if(cosTheta(wi)<0.0||cosTheta(wo)<0.0)"<<endl

<<"
returnvec3(0.0);"<<endl

<<"vec3diffuseRef="<<depNames[1]<<"(uv);"<<endl

<<"returndiffuseRef*inv_pi*cosTheta(wo);"<<endl

<<"}"<<endl;

MTS_DECLARE_CLASS()
private:

ref<constTexture>m_specularReflectance;

ref<constTexture>m_diffuseReflectance;

ref<constTexture>m_alpha;

ref<Shader>m_specularReflectanceShader;

ref<Shader>m_diffuseReflectanceShader;

ref<Shader>m_alphaShader;

Floatm_R0;
};
Shader*RoughPlastic::createShader(Renderer*renderer)const{

returnnewRoughPlasticShader(renderer,

m_specularReflectance.get(),m_diffuseReflectance.get(),

m_alpha.get(),m_eta);
}
MTS_IMPLEMENT_CLASS(RoughPlasticShader,false,Shader)
MTS_IMPLEMENT_CLASS_S(RoughPlastic,false,BSDF)
MTS_EXPORT_PLUGIN(RoughPlastic,"RoughplasticBRDF");
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

78/84

9/12/2016

mitApi

MTS_NAMESPACE_END

https://raw.githubusercontent.com/mmanzi/gradientdomain
mitsuba/7f01a2c044440c774dd88afe05eea4acdc418f2c/src/bsdfs/thindielectric.cpp

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

79/84

9/12/2016

mitApi

#include<mitsuba/render/bsdf.h>
#include<mitsuba/hw/basicshader.h>
#include"ior.h"
MTS_NAMESPACE_BEGIN
/*!\plugin{thindielectric}{Thindielectricmaterial}
*\order{4}
*\parameters{
*\parameter{intIOR}{\Float\Or\String}{Interiorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{bk7}/1.5046}}
*\parameter{extIOR}{\Float\Or\String}{Exteriorindexofrefractionspecified
*numericallyorusingaknownmaterialname.\default{\texttt{air}/1.000277}}
*\parameter{specular\showbreakReflectance}{\Spectrum\Or\Texture}{Optional
*factorthatcanbeusedtomodulatethespecularreflectioncomponent.Note
*thatforphysicalrealism,thisparametershouldneverbetouched.\default{1.0}}
*\parameter{specular\showbreakTransmittance}{\Spectrum\Or\Texture}{Optional
*factorthatcanbeusedtomodulatethespeculartransmissioncomponent.Note
*thatforphysicalrealism,thisparametershouldneverbetouched.\default{1.0}}
*}
*
*Thispluginmodelsa\emph{thin}dielectricmaterialthatisembeddedinsideanother
*dielectricforinstance,glasssurroundedbyair.Theinteriorofthematerial
*isassumedtobesothinthatitseffectontransmittedraysisnegligible,
*Hence,lightexitssuchamaterialwithoutanyformofangulardeflection
*(thoughthereisstillspecularreflection).
*
*Thismodelshouldbeusedforthingslikeglasswindowsthatweremodeledusingonlya
*singlesheetoftrianglesorquads.Ontheotherhand,whenthewindowconsistsof
*properclosedgeometry,\pluginref{dielectric}istherightchoice.Thisisillustratedbelow:
*
*\begin{figure}[h]
*\setcounter{subfigure}{0}
*\centering
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

80/84

9/12/2016

mitApi

*\hfill
*\subfloat[The\pluginref{dielectric}pluginmodelsasingletransitionfromoneindexofrefractiontoanother]
*{\includegraphics[width=4.5cm]{images/bsdf_dielectric_figure.pdf}}\hfill
*\subfloat[The\pluginref{thindielectric}pluginmodelsapairofinterfacescausingatransientindexof
refractionchange]
*{\includegraphics[width=4.5cm]{images/bsdf_thindielectric_figure.pdf}}\hfill
*\subfloat[WindowsmodeledusingasinglesheetofgeometryarethemostfrequentapplicationofthisBSDF]
*

{\fbox{\includegraphics[width=4.5cm]{images/bsdf_thindielectric_window.jpg}}}\hspace*\fill
*\caption{
*\label{fig:thindielectricdiff}
*Anillustrationofthedifferencebetweenthe\pluginref{dielectric}and\pluginref{thindielectric}plugins}
*\end{figure}
*
*Theimplementationcorrectlyaccountsformultipleinternalreflections
*insidethethindielectricat\emph{nosignificantextracost},i.e.paths
*ofthetype$R,TRT,TR^3T,..$forreflectionand$TT,TR^2,TR^4T,..$for
*refraction,where$T$and$R$denoteindividualreflectionandrefraction
*events,respectively.
*/
classThinDielectric:publicBSDF{
public:

ThinDielectric(constProperties&props):BSDF(props){

/*Specifiestheinternalindexofrefractionattheinterface*/

FloatintIOR=lookupIOR(props,"intIOR","bk7");

/*Specifiestheexternalindexofrefractionattheinterface*/
FloatextIOR=lookupIOR(props,"extIOR","air");

if(intIOR<0||extIOR<0)

Log(EError,"Theinteriorandexteriorindicesof"

"refractionmustbepositive!");

m_eta=intIOR/extIOR;

m_specularReflectance=newConstantSpectrumTexture(

props.getSpectrum("specularReflectance",Spectrum(1.0f)));
m_specularTransmittance=newConstantSpectrumTexture(

props.getSpectrum("specularTransmittance",Spectrum(1.0f)));

ThinDielectric(Stream*stream,InstanceManager*manager)

:BSDF(stream,manager){

m_eta=stream>readFloat();

m_specularReflectance=static_cast<Texture*>(manager>getInstance(stream));

m_specularTransmittance=static_cast<Texture*>(manager>getInstance(stream));

configure();
}

voidserialize(Stream*stream,InstanceManager*manager)const{

BSDF::serialize(stream,manager);

voidconfigure(){

/*Verifytheinputparametersandfixthemifnecessary*/

m_specularReflectance=ensureEnergyConservation(

m_specularReflectance,"specularReflectance",1.0f);

m_specularTransmittance=ensureEnergyConservation(

m_specularTransmittance,"specularTransmittance",1.0f);

m_components.clear();
m_components.push_back(EDeltaReflection|EFrontSide|EBackSide

|(m_specularReflectance>isConstant()?0:ESpatiallyVarying));
m_components.push_back(ENull|EFrontSide|EBackSide

|(m_specularTransmittance>isConstant()?0:ESpatiallyVarying));

m_usesRayDifferentials=false;

m_usesRayDifferentials=

m_specularReflectance>usesRayDifferentials()||

m_specularTransmittance>usesRayDifferentials();

BSDF::configure();

voidaddChild(conststd::string&name,ConfigurableObject*child){

if(child>getClass()>derivesFrom(MTS_CLASS(Texture))){

stream>writeFloat(m_eta);
manager>serialize(stream,m_specularReflectance.get());
manager>serialize(stream,m_specularTransmittance.get());

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

81/84

9/12/2016

mitApi

if(name=="specularReflectance")

m_specularReflectance=static_cast<Texture*>(child);

elseif(name=="specularTransmittance")

m_specularTransmittance=static_cast<Texture*>(child);

else

BSDF::addChild(name,child);
}else{

BSDF::addChild(name,child);
}

///Reflectioninlocalcoordinates
inlineVectorreflect(constVector&wi)const{

returnVector(wi.x,wi.y,wi.z);
}

///Transmissioninlocalcoordinates
inlineVectortransmit(constVector&wi)const{

returnwi;
}

Spectrumeval(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolsampleReflection=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0)&&measure==EDiscrete;

boolsampleTransmission=(bRec.typeMask&ENull)

&&(bRec.component==1||bRec.component==1)&&measure==EDiscrete;

FloatR=fresnelDielectricExt(std::abs(Frame::cosTheta(bRec.wi)),m_eta),T=1R;

//Accountforinternalreflections:R'=R+TRT+TR^3T+..
if(R<1)

R+=T*T*R/(1R*R);

if(Frame::cosTheta(bRec.wi)*Frame::cosTheta(bRec.wo)>=0){

if(!sampleReflection||std::abs(dot(reflect(bRec.wi),bRec.wo)1)>DeltaEpsilon)

returnSpectrum(0.0f);

returnm_specularReflectance>eval(bRec.its)*R;
}else{

if(!sampleTransmission||std::abs(dot(transmit(bRec.wi),bRec.wo)1)>DeltaEpsilon)

returnSpectrum(0.0f);

Floatpdf(constBSDFSamplingRecord&bRec,EMeasuremeasure)const{

boolsampleReflection=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0)&&measure==EDiscrete;

boolsampleTransmission=(bRec.typeMask&ENull)

&&(bRec.component==1||bRec.component==1)&&measure==EDiscrete;

FloatR=fresnelDielectricExt(std::abs(Frame::cosTheta(bRec.wi)),m_eta),T=1R;

//Accountforinternalreflections:R'=R+TRT+TR^3T+..
if(R<1)

R+=T*T*R/(1R*R);

if(Frame::cosTheta(bRec.wi)*Frame::cosTheta(bRec.wo)>=0){

if(!sampleReflection||std::abs(dot(reflect(bRec.wi),bRec.wo)1)>DeltaEpsilon)

return0.0f;

returnsampleTransmission?R:1.0f;
}else{

if(!sampleTransmission||std::abs(dot(transmit(bRec.wi),bRec.wo)1)>DeltaEpsilon)

return0.0f;

Spectrumsample(BSDFSamplingRecord&bRec,Float&pdf,constPoint2&sample)const{

boolsampleReflection=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0);

boolsampleTransmission=(bRec.typeMask&ENull)

&&(bRec.component==1||bRec.component==1);

FloatR=fresnelDielectricExt(std::abs(Frame::cosTheta(bRec.wi)),m_eta),T=1R;

//Accountforinternalreflections:R'=R+TRT+TR^3T+..

returnm_specularTransmittance>eval(bRec.its)*(1R);

returnsampleReflection?1R:1.0f;

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

82/84

9/12/2016

mitApi

if(R<1)

R+=T*T*R/(1R*R);

if(sampleTransmission&&sampleReflection){

if(sample.x<=R){

bRec.sampledComponent=0;

bRec.sampledType=EDeltaReflection;

bRec.wo=reflect(bRec.wi);

bRec.eta=1.0f;

pdf=R;

returnm_specularTransmittance>eval(bRec.its);

}
}elseif(sampleReflection){

bRec.sampledComponent=0;

bRec.sampledType=EDeltaReflection;

bRec.wo=reflect(bRec.wi);

bRec.eta=1.0f;

pdf=1.0f;

returnm_specularReflectance>eval(bRec.its)*R;
}elseif(sampleTransmission){

bRec.sampledComponent=1;

bRec.sampledType=ENull;

bRec.wo=transmit(bRec.wi);

bRec.eta=1.0f;

pdf=1.0f;

returnSpectrum(0.0f);

Spectrumsample(BSDFSamplingRecord&bRec,constPoint2&sample)const{

boolsampleReflection=(bRec.typeMask&EDeltaReflection)

&&(bRec.component==1||bRec.component==0);

boolsampleTransmission=(bRec.typeMask&ENull)

&&(bRec.component==1||bRec.component==1);

FloatR=fresnelDielectricExt(Frame::cosTheta(bRec.wi),m_eta),T=1R;

//Accountforinternalreflections:R'=R+TRT+TR^3T+..
if(R<1)

R+=T*T*R/(1R*R);

if(sampleTransmission&&sampleReflection){

if(sample.x<=R){

bRec.sampledComponent=0;

bRec.sampledType=EDeltaReflection;

bRec.wo=reflect(bRec.wi);

bRec.eta=1.0f;

returnm_specularTransmittance>eval(bRec.its);

}
}elseif(sampleReflection){

bRec.sampledComponent=0;

bRec.sampledType=EDeltaReflection;

bRec.wo=reflect(bRec.wi);

bRec.eta=1.0f;

returnm_specularReflectance>eval(bRec.its)*R;
}elseif(sampleTransmission){

bRec.sampledComponent=1;

bRec.sampledType=ENull;

returnm_specularReflectance>eval(bRec.its);
}else{

bRec.sampledComponent=1;

bRec.sampledType=ENull;

bRec.wo=transmit(bRec.wi);

bRec.eta=1.0f;

pdf=1R;

returnm_specularTransmittance>eval(bRec.its)*(1R);

returnm_specularReflectance>eval(bRec.its);
}else{

bRec.sampledComponent=1;

bRec.sampledType=ENull;

bRec.wo=transmit(bRec.wi);

bRec.eta=1.0f;

file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

83/84

9/12/2016

mitApi

bRec.wo=transmit(bRec.wi);
bRec.eta=1.0f;

returnm_specularTransmittance>eval(bRec.its)*(1R);

returnSpectrum(0.0f);

FloatgetEta()const{

/*TherrelativeIORacrossthisinterfaceis1,sincetheinternal

materialisthin:itbeginsandendshere.*/

return1.0f;
}

FloatgetRoughness(constIntersection&its,intcomponent)const{

return0.0f;
}

std::stringtoString()const{

std::ostringstreamoss;

oss<<"ThinDielectric["<<endl

<<"id=\""<<getID()<<"\","<<endl

<<"eta="<<m_eta<<","<<endl

<<"specularReflectance="<<indent(m_specularReflectance>toString())<<","<<endl

<<"specularTransmittance="<<indent(m_specularTransmittance>toString())<<endl

<<"]";

returnoss.str();
}

Shader*createShader(Renderer*renderer)const;

MTS_DECLARE_CLASS()
private:

Floatm_eta;

ref<Texture>m_specularTransmittance;

ref<Texture>m_specularReflectance;
};
/*Fakeglassshaderitisreallyhopelesstovisualize
thismaterialintheVPLrenderer,solet'strytodoatleast
somethingthatsuggeststhepresenceofatransparentboundary*/
classThinDielectricShader:publicShader{
public:

ThinDielectricShader(Renderer*renderer):

Shader(renderer,EBSDFShader){

m_flags=ETransparent;

FloatgetAlpha()const{

return0.3f;
}

voidgenerateCode(std::ostringstream&oss,

conststd::string&evalName,

conststd::vector<std::string>&depNames)const{

oss<<"vec3"<<evalName<<"(vec2uv,vec3wi,vec3wo){"<<endl

<<"if(cosTheta(wi)<0.0||cosTheta(wo)<0.0)"<<endl

<<"
returnvec3(0.0);"<<endl

<<"returnvec3(inv_pi*cosTheta(wo));"<<endl

<<"}"<<endl

<<endl

<<"vec3"<<evalName<<"_diffuse(vec2uv,vec3wi,vec3wo){"<<endl

<<"return"<<evalName<<"(uv,wi,wo);"<<endl

<<"}"<<endl;
}

};

MTS_DECLARE_CLASS()

Shader*ThinDielectric::createShader(Renderer*renderer)const{

returnnewThinDielectricShader(renderer);
}
MTS_IMPLEMENT_CLASS(ThinDielectricShader,false,Shader)
MTS_IMPLEMENT_CLASS_S(ThinDielectric,false,BSDF)
MTS_EXPORT_PLUGIN(ThinDielectric,"ThindielectricBSDF");
MTS_NAMESPACE_END
file:///C:/Users/sys/Desktop/Nueva%20carpeta/salida/salida25/subsalida1_25/mitsubaapi/mitApi

84/84

You might also like