got the rough plastic material to work properly again

metadata
Wenzel Jakob 2011-09-17 17:07:40 -04:00
parent 4cd971e274
commit 03264f9913
12 changed files with 159 additions and 119 deletions

View File

@ -369,7 +369,7 @@ public:
<< "}" << endl
<< endl
<< "vec3 " << evalName << "_diffuse(vec2 uv, vec3 wi, vec3 wo) {" << endl
<< " return " << evalName << "_R0 * 0.31831 * cosTheta(wo);"<< endl
<< " return " << evalName << "_R0 * inv_pi * cosTheta(wo);"<< endl
<< "}" << endl;
}
MTS_DECLARE_CLASS()

View File

@ -171,7 +171,7 @@ public:
oss << "vec3 " << evalName << "(vec2 uv, vec3 wi, vec3 wo) {" << endl
<< " if (cosTheta(wi) * cosTheta(wo) >= 0.0)" << endl
<< " return vec3(0.0);" << endl
<< " return " << depNames[0] << "(uv) * 0.31831 * abs(cosTheta(wo));" << endl
<< " return " << depNames[0] << "(uv) * inv_pi * abs(cosTheta(wo));" << endl
<< "}" << endl
<< endl
<< "vec3 " << evalName << "_diffuse(vec2 uv, vec3 wi, vec3 wo) {" << endl

View File

@ -203,7 +203,7 @@ public:
oss << "vec3 " << evalName << "(vec2 uv, vec3 wi, vec3 wo) {" << endl
<< " if (cosTheta(wi) < 0.0 || cosTheta(wo) < 0.0)" << endl
<< " return vec3(0.0);" << endl
<< " return " << depNames[0] << "(uv) * 0.31831 * cosTheta(wo);" << endl
<< " return " << depNames[0] << "(uv) * inv_pi * cosTheta(wo);" << endl
<< "}" << endl
<< endl
<< "vec3 " << evalName << "_diffuse(vec2 uv, vec3 wi, vec3 wo) {" << endl

View File

@ -291,7 +291,7 @@ public:
<< " reducedAlbedo[i] = reducedSigmaT[i] > 0.0 ? reducedSigmaS[i]/reducedSigmaT[i] : 0.0;" << endl
<< " vec3 rootExp = sqrt((1.0 - reducedAlbedo) * 3.0);" << endl
<< " return (reducedAlbedo * 0.5) * (1+exp(-rootExp*(4.0/3.0 * " << endl
<< " " << evalName << "_A" << "))) * exp(-rootExp) * 0.31831 * cosThetaO;" << endl
<< " " << evalName << "_A" << "))) * exp(-rootExp) * inv_pi * cosThetaO;" << endl
<< "}" << endl
<< endl
<< "vec3 " << evalName << "_diffuse(vec2 uv, vec3 wi, vec3 wo) {" << endl

View File

@ -333,13 +333,13 @@ public:
<< " if (alpha > 0.0)" << endl
<< " specRef = pow(alpha, exponent) * " << endl
<< " (exponent + 2) * 0.15915;" << endl
<< " return (" << depNames[1] << "(uv) * 0.31831" << endl
<< " return (" << depNames[1] << "(uv) * inv_pi" << endl
<< " + " << depNames[2] << "(uv) * specRef) * cosTheta(wo);" << endl
<< "}" << endl
<< "vec3 " << evalName << "_diffuse(vec2 uv, vec3 wi, vec3 wo) {" << endl
<< " if (wi.z <= 0.0 || wo.z <= 0.0)" << endl
<< " return vec3(0.0);" << endl
<< " return " << depNames[1] << "(uv) * (0.31831 * cosTheta(wo));" << endl
<< " return " << depNames[1] << "(uv) * (inv_pi * cosTheta(wo));" << endl
<< "}" << endl;
}

View File

@ -35,10 +35,10 @@ MTS_NAMESPACE_BEGIN
* for physical realism, this parameter should never be touched. \default{1.0}}
* \parameter{diffuse\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
* factor used to modulate the diffuse reflection component\default{0.5}}
* \parameter{preserveColors}{\Boolean}{
* Account for color shifts due to internal scattering? See the main text
* for a detailed description.\default{Don't account for them and
* preserve the colors, i.e. \code{true}}
* \parameter{nonlinear}{\Boolean}{
* Account for nonlinear color shifts due to internal scattering? See the
* main text for details.\default{Don't account for them and
* preserve the texture colors, i.e. \code{false}}
* }
* }
*
@ -75,11 +75,11 @@ MTS_NAMESPACE_BEGIN
*
* \renderings{
* \medrendering{Diffuse textured rendering}{bsdf_plastic_diffuse}
* \medrendering{Plastic, \code{preserveColors=true}}{bsdf_plastic_preserve}
* \medrendering{Plastic, \code{preserveColors=false}}{bsdf_plastic_nopreserve}
* \medrendering{Plastic, \code{nonlinear=false}}{bsdf_plastic_preserve}
* \medrendering{Plastic, \code{nonlinear=true}}{bsdf_plastic_nopreserve}
* \caption{
* \label{fig:plastic-preservecolors}
* When asked to do so, this model can account for subtle color shifts due
* \label{fig:plastic-nonlinear}
* When asked to do so, this model can account for subtle nonlinear color shifts due
* to internal scattering processes. The above images show a textured
* object first rendered using \pluginref{diffuse}, then
* \pluginref{plastic} with the default parameters, and finally using
@ -92,8 +92,8 @@ MTS_NAMESPACE_BEGIN
* base layer on its own---in particular, the material color will tend to shift towards
* darker colors with higher saturation. Since this can be counter-intuitive when
* using bitmap textures, these color shifts are disabled by default. Specify
* the parameter \code{preserveColors=false} to enable them.
* \figref{plastic-preservecolors} illustrates this effect.
* the parameter \code{nonlinear=true} to enable them.
* \figref{plastic-nonlinear} illustrates this effect.
*
* Similar to the \pluginref{dielectric} plugin, this model allows to specify
* IOR values either numerically, or based on a list of known materials (see
@ -130,7 +130,7 @@ public:
m_diffuseReflectance = new ConstantSpectrumTexture(
props.getSpectrum("diffuseReflectance", Spectrum(0.5f)));
m_preserveColors = props.getBoolean("preserveColors", true);
m_nonlinear = props.getBoolean("nonlinear", false);
m_specularSamplingWeight = 0.0f;
}
@ -139,7 +139,7 @@ public:
: BSDF(stream, manager) {
m_intIOR = stream->readFloat();
m_extIOR = stream->readFloat();
m_preserveColors = stream->readBool();
m_nonlinear = stream->readBool();
m_specularReflectance = static_cast<Texture *>(manager->getInstance(stream));
m_diffuseReflectance = static_cast<Texture *>(manager->getInstance(stream));
configure();
@ -153,7 +153,8 @@ public:
m_diffuseReflectance, "diffuseReflectance", 1.0f);
/* Numerically approximate the diffuse Fresnel reflectance */
m_fdr = fresnelDiffuseReflectance(m_extIOR / m_intIOR, false);
m_fdrInt = fresnelDiffuseReflectance(m_extIOR / m_intIOR, false);
m_fdrExt = fresnelDiffuseReflectance(m_intIOR / m_extIOR, false);
/* Compute weights that further steer samples towards
the specular or diffuse components */
@ -162,8 +163,8 @@ public:
m_specularSamplingWeight = sAvg / (dAvg + sAvg);
Float eta = m_extIOR / m_intIOR;
m_eta2 = eta*eta;
Float invEta = m_extIOR / m_intIOR;
m_invEta2 = invEta*invEta;
m_usesRayDifferentials =
m_specularReflectance->usesRayDifferentials() ||
@ -178,9 +179,8 @@ public:
BSDF::configure();
}
Spectrum getDiffuseReflectance(const Intersection &its) const {
return m_diffuseReflectance->getValue(its);
return m_diffuseReflectance->getValue(its) * (1-m_fdrExt);
}
void serialize(Stream *stream, InstanceManager *manager) const {
@ -188,7 +188,7 @@ public:
stream->writeFloat(m_intIOR);
stream->writeFloat(m_extIOR);
stream->writeBool(m_preserveColors);
stream->writeBool(m_nonlinear);
manager->serialize(stream, m_specularReflectance.get());
manager->serialize(stream, m_diffuseReflectance.get());
}
@ -232,11 +232,11 @@ public:
Float Fr2 = fresnel(Frame::cosTheta(bRec.wo), m_extIOR, m_intIOR);
Spectrum diff = m_diffuseReflectance->getValue(bRec.its);
if (m_preserveColors)
diff /= 1 - m_fdr;
if (m_nonlinear)
diff /= Spectrum(1) - diff * m_fdrInt;
else
diff /= Spectrum(1) - diff * m_fdr;
return diff * (INV_PI * Frame::cosTheta(bRec.wo) * m_eta2 * (1-Fr) * (1-Fr2));
diff /= 1 - m_fdrInt;
return diff * (INV_PI * Frame::cosTheta(bRec.wo) * m_invEta2 * (1-Fr) * (1-Fr2));
}
return Spectrum(0.0f);
@ -305,12 +305,12 @@ public:
Float Fr2 = fresnel(Frame::cosTheta(bRec.wo), m_extIOR, m_intIOR);
Spectrum diff = m_diffuseReflectance->getValue(bRec.its);
if (m_preserveColors)
diff /= 1 - m_fdr;
if (m_nonlinear)
diff /= Spectrum(1) - m_fdrInt*diff;
else
diff /= Spectrum(1) - m_fdr*diff;
diff /= 1 - m_fdrInt;
return diff * (m_eta2 * (1-Fr) * (1-Fr2) / (1-probSpecular));
return diff * (m_invEta2 * (1-Fr) * (1-Fr2) / (1-probSpecular));
}
} else if (hasSpecular) {
bRec.sampledComponent = 0;
@ -324,12 +324,12 @@ public:
bRec.sampledType = EDiffuseReflection;
Spectrum diff = m_diffuseReflectance->getValue(bRec.its);
if (m_preserveColors)
diff /= 1 - m_fdr;
if (m_nonlinear)
diff /= Spectrum(1) - diff*m_fdrInt;
else
diff /= Spectrum(1) - m_fdr*diff;
diff /= 1 - m_fdrInt;
return diff * (m_eta2 * (1-Fr) * (1-Fr2));
return diff * (m_invEta2 * (1-Fr) * (1-Fr2));
}
}
@ -367,14 +367,14 @@ public:
Float Fr2 = fresnel(Frame::cosTheta(bRec.wo), m_extIOR, m_intIOR);
Spectrum diff = m_diffuseReflectance->getValue(bRec.its);
if (m_preserveColors)
diff /= 1 - m_fdr;
if (m_nonlinear)
diff /= Spectrum(1) - diff*m_fdrInt;
else
diff /= Spectrum(1) - m_fdr*diff;
diff /= 1 - m_fdrInt;
pdf = (1-probSpecular) * Frame::cosTheta(bRec.wo) * INV_PI;
return diff * (m_eta2 * (1-Fr) * (1-Fr2) / (1-probSpecular));
return diff * (m_invEta2 * (1-Fr) * (1-Fr2) / (1-probSpecular));
}
} else if (hasSpecular) {
bRec.sampledComponent = 0;
@ -391,12 +391,12 @@ public:
pdf = Frame::cosTheta(bRec.wo) * INV_PI;
Spectrum diff = m_diffuseReflectance->getValue(bRec.its);
if (m_preserveColors)
diff /= 1 - m_fdr;
if (m_nonlinear)
diff /= Spectrum(1) - diff*m_fdrInt;
else
diff /= Spectrum(1) - m_fdr*diff;
diff /= 1 - m_fdrInt;
return diff * (m_eta2 * (1-Fr) * (1-Fr2));
return diff * (m_invEta2 * (1-Fr) * (1-Fr2));
}
}
@ -410,21 +410,23 @@ public:
<< " diffuseReflectance = " << indent(m_diffuseReflectance->toString()) << "," << endl
<< " specularSamplingWeight = " << m_specularSamplingWeight << "," << endl
<< " diffuseSamplingWeight = " << (1-m_specularSamplingWeight) << "," << endl
<< " preserveColors = " << m_preserveColors << "," << endl
<< " nonlinear = " << m_nonlinear << "," << endl
<< " intIOR = " << m_intIOR << "," << endl
<< " extIOR = " << m_extIOR << "," << endl
<< " fdr = " << m_fdr << endl
<< " fdrInt = " << m_fdrInt << "," << endl
<< " fdrExt = " << m_fdrExt << endl
<< "]";
return oss.str();
}
MTS_DECLARE_CLASS()
private:
Float m_intIOR, m_extIOR, m_fdr, m_eta2;
Float m_intIOR, m_extIOR;
Float m_fdrInt, m_fdrExt, m_invEta2;
ref<Texture> m_diffuseReflectance;
ref<Texture> m_specularReflectance;
Float m_specularSamplingWeight;
bool m_preserveColors;
bool m_nonlinear;
};
/**
@ -512,12 +514,12 @@ public:
<< " float G = " << evalName << "_G(H, wi, wo);" << endl
<< " float F = " << evalName << "_schlick(1-dot(wi, H));" << endl
<< " return specRef * (F * D * G / (4*cosTheta(wi))) + " << endl
<< " diffuseRef * ((1-F) * cosTheta(wo) * 0.31831);" << endl
<< " diffuseRef * ((1-F) * cosTheta(wo) * inv_pi);" << endl
<< "}" << endl
<< endl
<< "vec3 " << evalName << "_diffuse(vec2 uv, vec3 wi, vec3 wo) {" << endl
<< " vec3 diffuseRef = " << depNames[1] << "(uv);" << endl
<< " return diffuseRef * 0.31831 * cosTheta(wo);"<< endl
<< " return diffuseRef * inv_pi * cosTheta(wo);"<< endl
<< "}" << endl;
}
MTS_DECLARE_CLASS()

View File

@ -517,7 +517,7 @@ public:
<< "}" << endl
<< endl
<< "vec3 " << evalName << "_diffuse(vec2 uv, vec3 wi, vec3 wo) {" << endl
<< " return " << evalName << "_R0 * 0.31831 * cosTheta(wo);"<< endl
<< " return " << evalName << "_R0 * inv_pi * cosTheta(wo);"<< endl
<< "}" << endl;
}
MTS_DECLARE_CLASS()

View File

@ -333,13 +333,13 @@ public:
<< " tanBeta = sinTheta(wo) / cosTheta(wo);" << endl
<< " }" << endl
<< " float value = A + B * maxCos * sinAlpha * tanBeta;" << endl
<< " return " << depNames[0] << "(uv) * 0.31831 * cosTheta(wo) * value;" << endl
<< " return " << depNames[0] << "(uv) * inv_pi * cosTheta(wo) * value;" << endl
<< "}" << endl
<< endl
<< "vec3 " << evalName << "_diffuse(vec2 uv, vec3 wi, vec3 wo) {" << endl
<< " if (cosTheta(wi) <= 0.0 || cosTheta(wo) <= 0.0)" << endl
<< " return vec3(0.0);" << endl
<< " return " << depNames[0] << "(uv) * 0.31831 * cosTheta(wo);" << endl
<< " return " << depNames[0] << "(uv) * inv_pi * cosTheta(wo);" << endl
<< "}" << endl;
}

View File

@ -42,7 +42,7 @@ MTS_NAMESPACE_BEGIN
* Due to the underlying microfacet theory,
* the use of this distribution here leads to more realistic
* behavior than the separately available \pluginref{phong} plugin.
* \vspace{-4mm}
* \vspace{-3mm}
* \end{enumerate}
* }
* \parameter{alpha}{\Float}{
@ -60,26 +60,22 @@ MTS_NAMESPACE_BEGIN
* that for physical realism, this parameter should never be touched. \default{1.0}}
* \parameter{diffuse\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
* factor used to modulate the diffuse reflection component\default{0.5}}
* \parameter{preserveColors}{\Boolean}{
* Account for color shifts due to internal scattering? See the main text
* for a detailed description.\default{Don't account for them and
* preserve the colors, i.e. \code{true}}
* }\vspace{-1mm}
* \parameter{nonlinear}{\Boolean}{
* Account for nonlinear color shifts due to internal scattering? See the
* main text for details.\default{Don't account for them and
* preserve the texture colors, i.e. \code{false}}
* }
* }
* \renderings{
* \rendering{Beckmann, $\alpha=0.1$}{bsdf_roughplastic_beckmann}
* \rendering{GGX, $\alpha=0.3$}{bsdf_roughplastic_ggx}
* }\vspace{-1mm}
* }
*
* This plugin implements a realistic microfacet scattering model for rendering
* rough dielectric materials with internal scattering, such as plastic. It can
* be interpreted as a fancy version of the Cook-Torrance model and should be
* preferred over empirical models like \pluginref{phong} and \pluginref{ward}
* when possible.
* \renderings{
* \setcounter{subfigure}{2}
* \rendering{Beckmann, $\alpha=0.05$, diffuseReflectance=0}
* {bsdf_roughplastic_beckmann_lacquer}
* }
*
* Microfacet theory describes rough surfaces as an arrangement of unresolved and
* ideally specular facets, whose normal directions are given by a specially
@ -112,6 +108,12 @@ MTS_NAMESPACE_BEGIN
* which describe a white polypropylene plastic material with a light amount
* of roughness modeled using the Beckmann distribution.
*
* \renderings{
* \setcounter{subfigure}{2}
* \rendering{Beckmann, $\alpha=0.05$, diffuseReflectance=0}
* {bsdf_roughplastic_beckmann_lacquer}
* }
*
* To get an intuition about the effect of the surface roughness
* parameter $\alpha$, consider the following approximate differentiation:
* a value of $\alpha=0.001-0.01$ corresponds to a material
@ -119,14 +121,15 @@ MTS_NAMESPACE_BEGIN
* otherwise smooth surface finish, $\alpha=0.1$ is relatively rough,
* and $\alpha=0.3-0.7$ is \emph{extremely} rough (e.g. an etched or ground
* finish). Values significantly above that are probably not too realistic.
*
*
* When rendering with the Phong microfacet
* distributions, a conversion is used to turn the specified
* $\alpha$ roughness value into the Phong exponent.
* This is done in a way, such that the different
* distributions all produce a similar appearance for
* the same value of $\alpha$.
* \begin{xml}[caption={A material definition for rough, black laquer.}, label=lst:roughplastic-lacquer]
* \begin{xml}[caption={A material definition for rough, black laquer.},
* label=lst:roughplastic-lacquer]
* <bsdf type="roughplastic">
* <string name="distribution" value="beckmann"/>
* <float name="alpha" value="0.05"/>
@ -162,7 +165,7 @@ public:
Log(EError, "The 'roughplastic' plugin currently does not support "
"anisotropic microfacet distributions!");
m_preserveColors = props.getBoolean("preserveColors", true);
m_nonlinear = props.getBoolean("nonlinear", true);
m_alpha = new ConstantFloatTexture(
props.getFloat("alpha", 0.1f));
@ -180,7 +183,7 @@ public:
m_alpha = static_cast<Texture *>(manager->getInstance(stream));
m_intIOR = stream->readFloat();
m_extIOR = stream->readFloat();
m_preserveColors = stream->readBool();
m_nonlinear = stream->readBool();
configure();
}
@ -210,23 +213,26 @@ public:
m_specularSamplingWeight = sAvg / (dAvg + sAvg);
Float eta = m_intIOR / m_extIOR;
m_invEta2 = 1.0f / (eta*eta);
if (!m_roughTransmittance.get()) {
if (!m_externalRoughTransmittance.get()) {
/* Load precomputed data used to compute the rough
transmittance through the dielectric interface */
m_roughTransmittance = new RoughTransmittance(
m_externalRoughTransmittance = new RoughTransmittance(
m_distribution.getType());
m_roughTransmittance->checkEta(eta);
m_roughTransmittance->checkAlpha(m_alpha->getMinimum().average());
m_roughTransmittance->checkAlpha(m_alpha->getMaximum().average());
m_externalRoughTransmittance->checkEta(eta);
m_externalRoughTransmittance->checkAlpha(m_alpha->getMinimum().average());
m_externalRoughTransmittance->checkAlpha(m_alpha->getMaximum().average());
/* Reduce the rough transmittance data to a 2D slice */
m_roughTransmittance->setEta(eta);
m_internalRoughTransmittance = m_externalRoughTransmittance->clone();
m_externalRoughTransmittance->setEta(eta);
m_internalRoughTransmittance->setEta(1/eta);
/* If possible, even reduce it to a 1D slice */
if (constAlpha)
m_roughTransmittance->setAlpha(
m_externalRoughTransmittance->setAlpha(
m_alpha->getValue(Intersection()).average());
}
@ -238,7 +244,11 @@ public:
}
Spectrum getDiffuseReflectance(const Intersection &its) const {
return m_diffuseReflectance->getValue(its);
/* Evaluate the roughness texture */
Float alpha = m_alpha->getValue(its).average();
Float Ftr = m_externalRoughTransmittance->evalDiffuse(alpha);
return m_diffuseReflectance->getValue(its) * Ftr;
}
/// Helper function: reflect \c wi with respect to a given surface normal
@ -285,16 +295,16 @@ public:
if (hasDiffuse) {
Spectrum diff = m_diffuseReflectance->getValue(bRec.its);
Float T12 = m_roughTransmittance->eval(Frame::cosTheta(bRec.wi), alpha);
Float T21 = m_roughTransmittance->eval(Frame::cosTheta(bRec.wo), alpha);
Float Fdr = 1-m_roughTransmittance->evalDiffuse(alpha);
Float T12 = m_externalRoughTransmittance->eval(Frame::cosTheta(bRec.wi), alpha);
Float T21 = m_externalRoughTransmittance->eval(Frame::cosTheta(bRec.wo), alpha);
Float Fdr = 1-m_internalRoughTransmittance->evalDiffuse(alpha);
if (m_preserveColors)
diff /= 1-Fdr;
else
if (m_nonlinear)
diff /= Spectrum(1.0f) - diff * Fdr;
else
diff /= 1-Fdr;
result += diff * (INV_PI * Frame::cosTheta(bRec.wo) * T12 * T21);
result += diff * (INV_PI * Frame::cosTheta(bRec.wo) * T12 * T21 * m_invEta2);
}
return result;
@ -322,7 +332,7 @@ public:
Float probDiffuse, probSpecular;
if (hasSpecular && hasDiffuse) {
/* Find the probability of sampling the specular component */
probSpecular = 1-m_roughTransmittance->eval(Frame::cosTheta(bRec.wi), alpha);
probSpecular = 1-m_externalRoughTransmittance->eval(Frame::cosTheta(bRec.wi), alpha);
/* Reallocate samples */
probSpecular = (probSpecular*m_specularSamplingWeight) /
@ -370,7 +380,7 @@ public:
Float probSpecular;
if (hasSpecular && hasDiffuse) {
/* Find the probability of sampling the specular component */
probSpecular = 1 - m_roughTransmittance->eval(Frame::cosTheta(bRec.wi), alpha);
probSpecular = 1 - m_externalRoughTransmittance->eval(Frame::cosTheta(bRec.wi), alpha);
/* Reallocate samples */
probSpecular = (probSpecular*m_specularSamplingWeight) /
@ -424,7 +434,7 @@ public:
manager->serialize(stream, m_alpha.get());
stream->writeFloat(m_intIOR);
stream->writeFloat(m_extIOR);
stream->writeBool(m_preserveColors);
stream->writeBool(m_nonlinear);
}
void addChild(const std::string &name, ConfigurableObject *child) {
@ -452,7 +462,7 @@ public:
<< " diffuseReflectance = " << indent(m_diffuseReflectance->toString()) << "," << endl
<< " specularSamplingWeight = " << m_specularSamplingWeight << "," << endl
<< " diffuseSamplingWeight = " << (1-m_specularSamplingWeight) << "," << endl
<< " preserveColors = " << m_preserveColors << "," << endl
<< " nonlinear = " << m_nonlinear << "," << endl
<< " intIOR = " << m_intIOR << "," << endl
<< " extIOR = " << m_extIOR << endl
<< "]";
@ -464,13 +474,14 @@ public:
MTS_DECLARE_CLASS()
private:
MicrofacetDistribution m_distribution;
ref<RoughTransmittance> m_roughTransmittance;
ref<RoughTransmittance> m_externalRoughTransmittance;
ref<RoughTransmittance> m_internalRoughTransmittance;
ref<Texture> m_diffuseReflectance;
ref<Texture> m_specularReflectance;
ref<Texture> m_alpha;
Float m_intIOR, m_extIOR;
Float m_intIOR, m_extIOR, m_invEta2;
Float m_specularSamplingWeight;
bool m_preserveColors;
bool m_nonlinear;
};
/**
@ -520,7 +531,7 @@ public:
}
void bind(GPUProgram *program, const std::vector<int> &parameterIDs, int &textureUnitOffset) const {
program->setParameter(parameterIDs[1], m_R0);
program->setParameter(parameterIDs[0], m_R0);
}
void generateCode(std::ostringstream &oss,
@ -559,17 +570,18 @@ public:
<< " vec3 H = normalize(wi + wo);" << endl
<< " vec3 specRef = " << depNames[0] << "(uv);" << endl
<< " vec3 diffuseRef = " << depNames[1] << "(uv);" << endl
<< " float alpha = " << depNames[2] << "(uv)[0];" << endl
// << " float alpha = max(0.2, " << depNames[2] << "(uv)[0]);" << endl
<< " float alpha = 0.4;" << endl
<< " float D = " << evalName << "_D(H, alpha)" << ";" << endl
<< " float G = " << evalName << "_G(H, wi, wo);" << endl
<< " float F = " << evalName << "_schlick(1-dot(wi, H));" << endl
<< " return specRef * (F * D * G / (4*cosTheta(wi))) + " << endl
<< " diffuseRef * ((1-F) * cosTheta(wo) * 0.31831);" << endl
<< " diffuseRef * ((1-F) * cosTheta(wo) * inv_pi);" << endl
<< "}" << endl
<< endl
<< "vec3 " << evalName << "_diffuse(vec2 uv, vec3 wi, vec3 wo) {" << endl
<< " vec3 diffuseRef = " << depNames[1] << "(uv);" << endl
<< " return diffuseRef * 0.31831 * cosTheta(wo);"<< endl
<< " return diffuseRef * inv_pi * cosTheta(wo);"<< endl
<< "}" << endl;
}
MTS_DECLARE_CLASS()

View File

@ -102,17 +102,17 @@ public:
m_alphaSamples = fstream->readSize();
m_thetaSamples = fstream->readSize();
size_t transSize = 2 * m_etaSamples * m_alphaSamples * m_thetaSamples;
size_t diffTransSize = 2 * m_etaSamples * m_alphaSamples;
m_transSize = 2 * m_etaSamples * m_alphaSamples * m_thetaSamples;
m_diffTransSize = 2 * m_etaSamples * m_alphaSamples;
SLog(EDebug, "Loading " SIZE_T_FMT "x" SIZE_T_FMT "x" SIZE_T_FMT
" (%s) rough transmittance samples from \"%s\"", 2*m_etaSamples,
m_alphaSamples, m_thetaSamples,
memString((transSize + diffTransSize) * sizeof(float)).c_str(),
memString((m_transSize + m_diffTransSize) * sizeof(float)).c_str(),
sourceFile.file_string().c_str());
m_trans = new Float[transSize];
m_diffTrans = new Float[diffTransSize];
m_trans = new Float[m_transSize];
m_diffTrans = new Float[m_diffTransSize];
m_etaFixed = false;
m_alphaFixed = false;
@ -125,8 +125,8 @@ public:
"[%.4f, %.1f] and roughness range [%.4f, %.1f]", m_etaMin,
m_etaMax, m_alphaMin, m_alphaMax);
float *temp = new float[transSize + diffTransSize];
fstream->readSingleArray(temp, transSize + diffTransSize);
float *temp = new float[m_transSize + m_diffTransSize];
fstream->readSingleArray(temp, m_transSize + m_diffTransSize);
float *ptr = temp;
size_t fdrEntry = 0, dataEntry = 0;
@ -282,11 +282,11 @@ public:
if (m_etaFixed)
return;
size_t transSize = m_alphaSamples * m_thetaSamples;
size_t diffTransSize = m_alphaSamples;
m_transSize = m_alphaSamples * m_thetaSamples;
m_diffTransSize = m_alphaSamples;
SLog(EDebug, "Reducing dimension from 3D to 2D (%s), eta = %f",
memString((transSize + diffTransSize) * sizeof(Float)).c_str(), eta);
memString((m_transSize + m_diffTransSize) * sizeof(Float)).c_str(), eta);
Float *trans = m_trans,
*diffTrans = m_diffTrans;
@ -305,8 +305,8 @@ public:
Float warpedEta = std::pow((eta - m_etaMin)
/ (m_etaMax-m_etaMin), 0.25f);
Float *newTrans = new Float[transSize];
Float *newDiffTrans = new Float[diffTransSize];
Float *newTrans = new Float[m_transSize];
Float *newDiffTrans = new Float[m_diffTransSize];
Float dAlpha = 1.0f / (m_alphaSamples - 1),
dTheta = 1.0f / (m_thetaSamples - 1);
@ -344,17 +344,17 @@ public:
if (m_alphaFixed)
return;
size_t transSize = m_thetaSamples;
size_t diffTransSize = 1;
m_transSize = m_thetaSamples;
m_diffTransSize = 1;
SLog(EDebug, "Reducing dimension from 2D to 1D (%s), alpha = %f",
memString((transSize + diffTransSize) * sizeof(Float)).c_str(), alpha);
memString((m_transSize + m_diffTransSize) * sizeof(Float)).c_str(), alpha);
Float warpedAlpha = std::pow((alpha - m_alphaMin)
/ (m_alphaMax-m_alphaMin), 0.25f);
Float *newTrans = new Float[transSize];
Float *newDiffTrans = new Float[diffTransSize];
Float *newTrans = new Float[m_transSize];
Float *newDiffTrans = new Float[m_diffTransSize];
Float dTheta = 1.0f / (m_thetaSamples - 1);
@ -388,12 +388,35 @@ public:
if (eta < 1)
eta = 1/eta;
if (eta < m_etaMin || eta > m_etaMax)
SLog(EError, "Error: the requested index of refraction eta=%f is"
" outside of the supported range [%f, %f]! Please update your "
" scene so that it uses realistic IOR values.", eta,
m_etaMin, m_etaMax);
SLog(EError, "Error: the requested relative index of refraction "
"eta=%f is outside of the supported range [%f, %f]! Please "
"update your scene so that it uses realistic IOR values.",
eta, m_etaMin, m_etaMax);
}
/// Create a deep copy of the current instance
ref<RoughTransmittance> clone() const {
RoughTransmittance *result = new RoughTransmittance();
result->m_name = m_name;
result->m_etaSamples = m_etaSamples;
result->m_alphaSamples = m_alphaSamples;
result->m_thetaSamples = m_thetaSamples;
result->m_etaFixed = m_etaFixed;
result->m_alphaFixed = m_alphaFixed;
result->m_etaMin = m_etaMin;
result->m_etaMax = m_etaMax;
result->m_alphaMin = m_alphaMin;
result->m_alphaMax = m_alphaMax;
result->m_transSize = m_transSize;
result->m_diffTransSize = m_diffTransSize;
result->m_trans = new Float[m_transSize];
result->m_diffTrans = new Float[m_diffTransSize];
memcpy(result->m_trans, m_trans, m_transSize * sizeof(Float));
memcpy(result->m_diffTrans, m_diffTrans, m_diffTransSize * sizeof(Float));
return result;
}
protected:
inline RoughTransmittance() { }
protected:
std::string m_name;
size_t m_etaSamples;
@ -403,6 +426,8 @@ protected:
bool m_alphaFixed;
Float m_etaMin, m_etaMax;
Float m_alphaMin, m_alphaMax;
size_t m_transSize;
size_t m_diffTransSize;
Float *m_trans, *m_diffTrans;
};

View File

@ -449,13 +449,13 @@ public:
<< " float factor2 = H.x / alphaU, factor3 = H.y / alphaV;" << endl
<< " float exponent = -(factor2*factor2 + factor3*factor3)/(H.z*H.z);" << endl
<< " float specRef = factor1 * exp(exponent);" << endl
<< " return (" << depNames[0] << "(uv) * 0.31831" << endl
<< " return (" << depNames[0] << "(uv) * inv_pi" << endl
<< " + " << depNames[1] << "(uv) * specRef) * cosTheta(wo);" << endl
<< "}" << endl
<< "vec3 " << evalName << "_diffuse(vec2 uv, vec3 wi, vec3 wo) {" << endl
<< " if (wi.z <= 0.0 || wo.z <= 0.0)" << endl
<< " return vec3(0.0);" << endl
<< " return " << depNames[0] << "(uv) * (0.31831 * cosTheta(wo));" << endl
<< " return " << depNames[0] << "(uv) * (inv_pi * cosTheta(wo));" << endl
<< "}" << endl;
}

View File

@ -503,6 +503,7 @@ void VPLShaderManager::configure(const VPL &vpl, const BSDF *bsdf,
<< "float sinPhi(vec3 v) { return v.y/sinTheta(v); }" << endl
<< "float cosPhi(vec3 v) { return v.x/sinTheta(v); }" << endl
<< "const float pi = 3.141592653589;" << endl
<< "const float inv_pi = 0.318309886183791;" << endl
<< endl;
std::string vplEvalName, bsdfEvalName, lumEvalName;