Mit Api
Mit Api
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>¶meterIDs)const
voidbind(GPUProgram*program,conststd::vector<int>¶meterIDs,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>¶meterIDs)const
voidbind(GPUProgram*program,conststd::vector<int>¶meterIDs,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>¶meterIDs)const
voidbind(GPUProgram*program,conststd::vector<int>¶meterIDs,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>¶meterIDs)const
voidbind(GPUProgram*program,conststd::vector<int>¶meterIDs,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>¶meterIDs)const
voidbind(GPUProgram*program,conststd::vector<int>¶meterIDs,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>¶meterIDs)const
voidbind(GPUProgram*program,conststd::vector<int>¶meterIDs,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