significant rehaul of the dielectric.cpp implementation. Fixed some OpenGL errors on MacOS X
parent
cb3dcdb377
commit
7c5f924fad
|
@ -17,17 +17,24 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mitsuba/render/bsdf.h>
|
#include <mitsuba/render/bsdf.h>
|
||||||
#include <mitsuba/render/sampler.h>
|
#include <mitsuba/render/consttexture.h>
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
const bool importanceSampleComponents = true;
|
/*! \plugin{dielectric}{Ideal dielectric/glass material}
|
||||||
|
*
|
||||||
/**
|
* \parameters{
|
||||||
|
* \parameter{intIOR}{\Float}{Interior index of refraction \default{1.5046}}
|
||||||
|
* \parameter{extIOR}{\Float}{Exterior index of refraction \default{1.0}}
|
||||||
|
* \parameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
|
||||||
|
* factor used to modulate the reflectance component\default{1.0}}
|
||||||
|
* \parameter{specular\showbreak Transmittance}{\Spectrum\Or\Texture}{Optional
|
||||||
|
* factor used to modulate the transmittance component\default{1.0}}
|
||||||
|
* }
|
||||||
|
*
|
||||||
* Models an interface between two materials with non-matched indices of refraction.
|
* Models an interface between two materials with non-matched indices of refraction.
|
||||||
* The microscopic surface structure is assumed to be perfectly flat, resulting
|
* The microscopic surface structure is assumed to be perfectly flat, resulting
|
||||||
* in a BSDF equal to a Dirac delta function.
|
* in a BSDF equal to a Dirac delta function.
|
||||||
*
|
|
||||||
* The default settings are set to a borosilicate glass BK7/air interface.
|
* The default settings are set to a borosilicate glass BK7/air interface.
|
||||||
*/
|
*/
|
||||||
class Dielectric : public BSDF {
|
class Dielectric : public BSDF {
|
||||||
|
@ -38,10 +45,11 @@ public:
|
||||||
m_intIOR = props.getFloat("intIOR", 1.5046f);
|
m_intIOR = props.getFloat("intIOR", 1.5046f);
|
||||||
/* Specifies the external index of refraction at the interface */
|
/* Specifies the external index of refraction at the interface */
|
||||||
m_extIOR = props.getFloat("extIOR", 1);
|
m_extIOR = props.getFloat("extIOR", 1);
|
||||||
/* Reflectance modulation term */
|
|
||||||
m_reflectance = props.getSpectrum("specularReflectance", Spectrum(1.0f));
|
m_specularReflectance = new ConstantSpectrumTexture(
|
||||||
/* Transmittance modulation term */
|
props.getSpectrum("specularReflectance", Spectrum(1.0f)));
|
||||||
m_transmittance = props.getSpectrum("specularTransmittance", Spectrum(1.0f));
|
m_specularTransmittance = new ConstantSpectrumTexture(
|
||||||
|
props.getSpectrum("specularTransmittance", Spectrum(1.0f)));
|
||||||
|
|
||||||
m_componentCount = 2;
|
m_componentCount = 2;
|
||||||
m_type = new unsigned int[m_componentCount];
|
m_type = new unsigned int[m_componentCount];
|
||||||
|
@ -55,8 +63,8 @@ public:
|
||||||
: BSDF(stream, manager) {
|
: BSDF(stream, manager) {
|
||||||
m_intIOR = stream->readFloat();
|
m_intIOR = stream->readFloat();
|
||||||
m_extIOR = stream->readFloat();
|
m_extIOR = stream->readFloat();
|
||||||
m_transmittance = Spectrum(stream);
|
m_specularReflectance = static_cast<Texture *>(manager->getInstance(stream));
|
||||||
m_reflectance = Spectrum(stream);
|
m_specularTransmittance = static_cast<Texture *>(manager->getInstance(stream));
|
||||||
|
|
||||||
m_componentCount = 2;
|
m_componentCount = 2;
|
||||||
m_type = new unsigned int[m_componentCount];
|
m_type = new unsigned int[m_componentCount];
|
||||||
|
@ -75,8 +83,8 @@ public:
|
||||||
|
|
||||||
stream->writeFloat(m_intIOR);
|
stream->writeFloat(m_intIOR);
|
||||||
stream->writeFloat(m_extIOR);
|
stream->writeFloat(m_extIOR);
|
||||||
m_transmittance.serialize(stream);
|
manager->serialize(stream, m_specularReflectance.get());
|
||||||
m_reflectance.serialize(stream);
|
manager->serialize(stream, m_specularTransmittance.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
Spectrum getDiffuseReflectance(const Intersection &its) const {
|
Spectrum getDiffuseReflectance(const Intersection &its) const {
|
||||||
|
@ -91,101 +99,187 @@ public:
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void reflect(const Vector &wo, Vector &wi) const {
|
/// Reflection in local coordinates
|
||||||
wi = Vector(-wo.x, -wo.y, wo.z);
|
inline Vector reflect(const Vector &wi) const {
|
||||||
|
return Vector(-wi.x, -wi.y, wi.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
Float refract(Float intIOR, Float extIOR,
|
/// Refraction in local coordinates
|
||||||
const Vector &wi, Vector &wo, ETransportQuantity quantity) const {
|
inline Vector refract(const Vector &wi, Float eta, Float cosThetaT) const {
|
||||||
Float cosThetaI = Frame::cosTheta(wi),
|
return Vector(-eta*wi.x, -eta*wi.y, cosThetaT);
|
||||||
etaI = extIOR, etaT = intIOR;
|
|
||||||
bool entering = cosThetaI > 0.0f;
|
|
||||||
|
|
||||||
if (!entering)
|
|
||||||
std::swap(etaT, etaI);
|
|
||||||
|
|
||||||
Float eta = etaI / etaT;
|
|
||||||
|
|
||||||
/* Using Snell's law, calculate the squared sine of the
|
|
||||||
angle between the normal and the transmitted ray */
|
|
||||||
Float sinThetaTSqr = eta*eta * Frame::sinTheta2(wi);
|
|
||||||
|
|
||||||
if (sinThetaTSqr > 1.0f) /* Total internal reflection! */
|
|
||||||
return 0.0f;
|
|
||||||
|
|
||||||
Float cosThetaT = std::sqrt(1.0f - sinThetaTSqr);
|
|
||||||
if (entering)
|
|
||||||
cosThetaT = -cosThetaT;
|
|
||||||
|
|
||||||
/* With cos(N, transmittedRay) avilable, calculating the
|
|
||||||
transmission direction is straightforward */
|
|
||||||
wo = Vector(-eta*wi.x, -eta*wi.y, cosThetaT);
|
|
||||||
|
|
||||||
/* Finally compute transmission coefficient. When transporting
|
|
||||||
radiance, account for the solid angle change at boundaries
|
|
||||||
with different indices of refraction. */
|
|
||||||
if (quantity == ERadiance)
|
|
||||||
return (etaI*etaI) / (etaT*etaT);
|
|
||||||
else
|
|
||||||
return 1.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Spectrum sample(BSDFQueryRecord &bRec, const Point2 &sample) const {
|
Spectrum sample(BSDFQueryRecord &bRec, const Point2 &sample) const {
|
||||||
Float pdf = 0;
|
|
||||||
Spectrum spec = Dielectric::sample(bRec, pdf, sample);
|
|
||||||
if (pdf == 0 || spec.isZero())
|
|
||||||
return Spectrum(0.0f);
|
|
||||||
return spec/pdf;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Spectrum sample(BSDFQueryRecord &bRec, Float &pdf, const Point2 &sample) const {
|
|
||||||
bool sampleReflection = (bRec.typeMask & EDeltaReflection)
|
bool sampleReflection = (bRec.typeMask & EDeltaReflection)
|
||||||
&& (bRec.component == -1 || bRec.component == 0);
|
&& (bRec.component == -1 || bRec.component == 0);
|
||||||
bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
|
bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
|
||||||
&& (bRec.component == -1 || bRec.component == 1);
|
&& (bRec.component == -1 || bRec.component == 1);
|
||||||
|
|
||||||
|
if (!sampleTransmission && !sampleReflection)
|
||||||
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
Float fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
|
Float cosThetaI = Frame::cosTheta(bRec.wi),
|
||||||
|
etaI = m_extIOR,
|
||||||
|
etaT = m_intIOR;
|
||||||
|
|
||||||
|
bool entering = cosThetaI > 0.0f;
|
||||||
|
|
||||||
|
/* Determine the respective indices of refraction */
|
||||||
|
if (!entering)
|
||||||
|
std::swap(etaI, etaT);
|
||||||
|
|
||||||
|
/* Using Snell's law, calculate the squared sine of the
|
||||||
|
angle between the normal and the transmitted ray */
|
||||||
|
Float eta = etaI / etaT,
|
||||||
|
sinThetaTSqr = eta*eta * Frame::sinTheta2(bRec.wi);
|
||||||
|
|
||||||
|
Float Fr, cosThetaT = 0;
|
||||||
|
if (sinThetaTSqr >= 1.0f) {
|
||||||
|
/* Total internal reflection */
|
||||||
|
Fr = 1.0f;
|
||||||
|
} else {
|
||||||
|
cosThetaT = std::sqrt(1.0f - sinThetaTSqr);
|
||||||
|
|
||||||
|
/* Compute the Fresnel refletance */
|
||||||
|
Fr = fresnelDielectric(std::abs(cosThetaI),
|
||||||
|
cosThetaT, etaI, etaT);
|
||||||
|
|
||||||
|
if (entering)
|
||||||
|
cosThetaT = -cosThetaT;
|
||||||
|
}
|
||||||
|
|
||||||
/* Calculate the refracted/reflected vectors+coefficients */
|
/* Calculate the refracted/reflected vectors+coefficients */
|
||||||
if (sampleTransmission && sampleReflection) {
|
if (sampleTransmission && sampleReflection) {
|
||||||
/* Importance sample according to the reflectance/transmittance */
|
/* Importance sample according to the reflectance/transmittance */
|
||||||
if (sample.x < (importanceSampleComponents ? fr : 0.5f)) {
|
if (sample.x <= Fr) {
|
||||||
reflect(bRec.wi, bRec.wo);
|
|
||||||
bRec.sampledComponent = 0;
|
bRec.sampledComponent = 0;
|
||||||
bRec.sampledType = EDeltaReflection;
|
bRec.sampledType = EDeltaReflection;
|
||||||
pdf = (importanceSampleComponents ? fr : 0.5f) * std::abs(Frame::cosTheta(bRec.wo));
|
bRec.wo = reflect(bRec.wi);
|
||||||
/* Cancel out the cosine term */
|
|
||||||
return m_reflectance * fr;
|
return m_specularReflectance->getValue(bRec.its)
|
||||||
|
/ std::abs(Frame::cosTheta(bRec.wo));
|
||||||
} else {
|
} else {
|
||||||
pdf = importanceSampleComponents ? (1-fr) : 0.5f;
|
|
||||||
bRec.sampledComponent = 1;
|
bRec.sampledComponent = 1;
|
||||||
bRec.sampledType = EDeltaTransmission;
|
bRec.sampledType = EDeltaTransmission;
|
||||||
|
|
||||||
Float result = refract(m_intIOR, m_extIOR, bRec.wi, bRec.wo, bRec.quantity);
|
/* Given cos(N, transmittedRay), compute the
|
||||||
if (result == 0)
|
transmitted direction */
|
||||||
return Spectrum(0.0f);
|
bRec.wo = refract(bRec.wi, eta, cosThetaT);
|
||||||
pdf *= std::abs(Frame::cosTheta(bRec.wo));
|
|
||||||
|
|
||||||
return m_transmittance * result * (1-fr);
|
/* When transporting radiance, account for the solid angle
|
||||||
|
change at boundaries with different indices of refraction. */
|
||||||
|
return m_specularTransmittance->getValue(bRec.its)
|
||||||
|
* (bRec.quantity == ERadiance ? (eta*eta) : (Float) 1)
|
||||||
|
/ std::abs(Frame::cosTheta(bRec.wo));
|
||||||
}
|
}
|
||||||
} else if (sampleReflection) {
|
} else if (sampleReflection) {
|
||||||
reflect(bRec.wi, bRec.wo);
|
|
||||||
bRec.sampledComponent = 0;
|
bRec.sampledComponent = 0;
|
||||||
bRec.sampledType = EDeltaReflection;
|
bRec.sampledType = EDeltaReflection;
|
||||||
pdf = std::abs(Frame::cosTheta(bRec.wo));
|
bRec.wo = reflect(bRec.wi);
|
||||||
return m_reflectance * fr;
|
return m_specularReflectance->getValue(bRec.its) * (Fr
|
||||||
} else if (sampleTransmission) {
|
/ std::abs(Frame::cosTheta(bRec.wo)));
|
||||||
|
} else {
|
||||||
bRec.sampledComponent = 1;
|
bRec.sampledComponent = 1;
|
||||||
bRec.sampledType = EDeltaTransmission;
|
bRec.sampledType = EDeltaTransmission;
|
||||||
|
|
||||||
Float result = refract(m_intIOR, m_extIOR, bRec.wi, bRec.wo, bRec.quantity);
|
if (Fr == 1.0f) /* Total internal reflection */
|
||||||
pdf = std::abs(Frame::cosTheta(bRec.wo));
|
|
||||||
if (result == 0)
|
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
return m_transmittance * result * (1-fr);
|
bRec.wo = refract(bRec.wi, eta, cosThetaT);
|
||||||
|
|
||||||
|
/* When transporting radiance, account for the solid angle
|
||||||
|
change at boundaries with different indices of refraction. */
|
||||||
|
return m_specularTransmittance->getValue(bRec.its)
|
||||||
|
* ((1-Fr) * (bRec.quantity == ERadiance ? (eta*eta) : (Float) 1))
|
||||||
|
/ std::abs(Frame::cosTheta(bRec.wo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spectrum sample(BSDFQueryRecord &bRec, Float &pdf, const Point2 &sample) const {
|
||||||
|
bool sampleReflection = (bRec.typeMask & EDeltaReflection)
|
||||||
|
&& (bRec.component == -1 || bRec.component == 0);
|
||||||
|
bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
|
||||||
|
&& (bRec.component == -1 || bRec.component == 1);
|
||||||
|
|
||||||
|
if (!sampleTransmission && !sampleReflection)
|
||||||
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
|
Float cosThetaI = Frame::cosTheta(bRec.wi),
|
||||||
|
etaI = m_extIOR,
|
||||||
|
etaT = m_intIOR;
|
||||||
|
|
||||||
|
bool entering = cosThetaI > 0.0f;
|
||||||
|
|
||||||
|
/* Determine the respective indices of refraction */
|
||||||
|
if (!entering)
|
||||||
|
std::swap(etaI, etaT);
|
||||||
|
|
||||||
|
/* Using Snell's law, calculate the squared sine of the
|
||||||
|
angle between the normal and the transmitted ray */
|
||||||
|
Float eta = etaI / etaT,
|
||||||
|
sinThetaTSqr = eta*eta * Frame::sinTheta2(bRec.wi);
|
||||||
|
|
||||||
|
Float Fr, cosThetaT = 0;
|
||||||
|
if (sinThetaTSqr >= 1.0f) {
|
||||||
|
/* Total internal reflection */
|
||||||
|
Fr = 1.0f;
|
||||||
|
} else {
|
||||||
|
cosThetaT = std::sqrt(1.0f - sinThetaTSqr);
|
||||||
|
|
||||||
|
/* Compute the Fresnel refletance */
|
||||||
|
Fr = fresnelDielectric(std::abs(cosThetaI),
|
||||||
|
cosThetaT, etaI, etaT);
|
||||||
|
|
||||||
|
if (entering)
|
||||||
|
cosThetaT = -cosThetaT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the refracted/reflected vectors+coefficients */
|
||||||
|
if (sampleTransmission && sampleReflection) {
|
||||||
|
/* Importance sample according to the reflectance/transmittance */
|
||||||
|
if (sample.x <= Fr) {
|
||||||
|
bRec.sampledComponent = 0;
|
||||||
|
bRec.sampledType = EDeltaReflection;
|
||||||
|
bRec.wo = reflect(bRec.wi);
|
||||||
|
|
||||||
|
pdf = Fr * std::abs(Frame::cosTheta(bRec.wo));
|
||||||
|
return m_specularReflectance->getValue(bRec.its) * Fr;
|
||||||
|
} else {
|
||||||
|
bRec.sampledComponent = 1;
|
||||||
|
bRec.sampledType = EDeltaTransmission;
|
||||||
|
|
||||||
|
/* Given cos(N, transmittedRay), compute the
|
||||||
|
transmitted direction */
|
||||||
|
bRec.wo = refract(bRec.wi, eta, cosThetaT);
|
||||||
|
|
||||||
|
pdf = (1-Fr) * std::abs(Frame::cosTheta(bRec.wo));
|
||||||
|
|
||||||
|
/* When transporting radiance, account for the solid angle
|
||||||
|
change at boundaries with different indices of refraction. */
|
||||||
|
return m_specularTransmittance->getValue(bRec.its)
|
||||||
|
* (1-Fr) * (bRec.quantity == ERadiance ? (eta*eta) : (Float) 1);
|
||||||
|
}
|
||||||
|
} else if (sampleReflection) {
|
||||||
|
bRec.sampledComponent = 0;
|
||||||
|
bRec.sampledType = EDeltaReflection;
|
||||||
|
bRec.wo = reflect(bRec.wi);
|
||||||
|
pdf = std::abs(Frame::cosTheta(bRec.wo));
|
||||||
|
return m_specularReflectance->getValue(bRec.its) * Fr;
|
||||||
|
} else {
|
||||||
|
bRec.sampledComponent = 1;
|
||||||
|
bRec.sampledType = EDeltaTransmission;
|
||||||
|
|
||||||
|
if (Fr == 1.0f) /* Total internal reflection */
|
||||||
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
|
bRec.wo = refract(bRec.wi, eta, cosThetaT);
|
||||||
|
pdf = std::abs(Frame::cosTheta(bRec.wo));
|
||||||
|
|
||||||
|
/* When transporting radiance, account for the solid angle
|
||||||
|
change at boundaries with different indices of refraction. */
|
||||||
|
return m_specularTransmittance->getValue(bRec.its)
|
||||||
|
* ((1-Fr) * (bRec.quantity == ERadiance ? (eta*eta) : (Float) 1));
|
||||||
}
|
}
|
||||||
return Spectrum(0.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Float pdfDelta(const BSDFQueryRecord &bRec) const {
|
Float pdfDelta(const BSDFQueryRecord &bRec) const {
|
||||||
|
@ -197,12 +291,8 @@ public:
|
||||||
|
|
||||||
Float result = 0.0f;
|
Float result = 0.0f;
|
||||||
if (sampleTransmission && sampleReflection) {
|
if (sampleTransmission && sampleReflection) {
|
||||||
if (!importanceSampleComponents) {
|
Float fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
|
||||||
result = 0.5f;
|
result = reflection ? fr : (1-fr);
|
||||||
} else {
|
|
||||||
Float fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
|
|
||||||
result = reflection ? fr : (1-fr);
|
|
||||||
}
|
|
||||||
} else if (sampleReflection) {
|
} else if (sampleReflection) {
|
||||||
result = reflection ? 1.0f : 0.0f;
|
result = reflection ? 1.0f : 0.0f;
|
||||||
} else if (sampleTransmission) {
|
} else if (sampleTransmission) {
|
||||||
|
@ -225,7 +315,7 @@ public:
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
if (reflection) {
|
if (reflection) {
|
||||||
return m_reflectance * fr;
|
return m_specularReflectance->getValue(bRec.its) * fr;
|
||||||
} else {
|
} else {
|
||||||
Float etaI = m_extIOR, etaT = m_intIOR;
|
Float etaI = m_extIOR, etaT = m_intIOR;
|
||||||
bool entering = Frame::cosTheta(bRec.wi) > 0.0f;
|
bool entering = Frame::cosTheta(bRec.wi) > 0.0f;
|
||||||
|
@ -235,7 +325,7 @@ public:
|
||||||
Float factor = (bRec.quantity == ERadiance)
|
Float factor = (bRec.quantity == ERadiance)
|
||||||
? (etaI*etaI) / (etaT*etaT) : 1.0f;
|
? (etaI*etaI) / (etaT*etaT) : 1.0f;
|
||||||
|
|
||||||
return m_transmittance * factor * (1 - fr);
|
return m_specularTransmittance->getValue(bRec.its) * factor * (1 - fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -245,8 +335,8 @@ public:
|
||||||
oss << "Dielectric[" << endl
|
oss << "Dielectric[" << endl
|
||||||
<< " intIOR = " << m_intIOR << "," << endl
|
<< " intIOR = " << m_intIOR << "," << endl
|
||||||
<< " extIOR = " << m_extIOR << "," << endl
|
<< " extIOR = " << m_extIOR << "," << endl
|
||||||
<< " reflectance = " << m_reflectance.toString() << "," << endl
|
<< " specularReflectance = " << indent(m_specularReflectance->toString()) << "," << endl
|
||||||
<< " transmittance = " << m_transmittance.toString() << endl
|
<< " specularTransmittance = " << indent(m_specularTransmittance->toString()) << endl
|
||||||
<< "]";
|
<< "]";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
@ -254,8 +344,8 @@ public:
|
||||||
MTS_DECLARE_CLASS()
|
MTS_DECLARE_CLASS()
|
||||||
private:
|
private:
|
||||||
Float m_intIOR, m_extIOR;
|
Float m_intIOR, m_extIOR;
|
||||||
Spectrum m_reflectance;
|
ref<Texture> m_specularTransmittance;
|
||||||
Spectrum m_transmittance;
|
ref<Texture> m_specularReflectance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,14 +33,14 @@ MTS_NAMESPACE_BEGIN
|
||||||
* Gaussian random surfaces. This is the default choice.
|
* Gaussian random surfaces. This is the default choice.
|
||||||
* \item \code{phong}: Classical $\cos^p\theta$ distribution.
|
* \item \code{phong}: Classical $\cos^p\theta$ distribution.
|
||||||
* The Phong exponent $p$ is obtained using a transformation that
|
* The Phong exponent $p$ is obtained using a transformation that
|
||||||
* produces roughness similar to a Beckmann distribution with the same
|
* produces roughness similar to a Beckmann distribution of the same
|
||||||
* parameter. Note that due to the underlying microfacet theory,
|
* parameter. Note that due to the underlying microfacet theory,
|
||||||
* the use of this distribution here leads to more realistic
|
* the use of this distribution here leads to more realistic
|
||||||
* behavior than the separately available \pluginref{phong} plugin.
|
* behavior than the separately available \pluginref{phong} plugin.
|
||||||
* \item \code{ggx}: New distribution proposed by
|
* \item \code{ggx}: New distribution proposed by
|
||||||
* Walter et al. meant to better handle the long
|
* Walter et al. meant to better handle the long
|
||||||
* tails observed in transmission measurements through
|
* tails observed in transmission measurements through
|
||||||
* ground glass.
|
* ground glass.
|
||||||
* \end{enumerate}
|
* \end{enumerate}
|
||||||
* Default: \code{beckmann}
|
* Default: \code{beckmann}
|
||||||
* }
|
* }
|
||||||
|
@ -51,11 +51,11 @@ MTS_NAMESPACE_BEGIN
|
||||||
* \default{0.1}
|
* \default{0.1}
|
||||||
* }
|
* }
|
||||||
* \parameter{intIOR}{\Float}{Interior index of refraction \default{1.5046}}
|
* \parameter{intIOR}{\Float}{Interior index of refraction \default{1.5046}}
|
||||||
* \parameter{extIOR}{\Float}{Exterior index of refraction \default{1}}
|
* \parameter{extIOR}{\Float}{Exterior index of refraction \default{1.0}}
|
||||||
* \parameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
|
* \parameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
|
||||||
* factor used to modulate the reflectance component\default{1}}
|
* factor used to modulate the reflectance component\default{1.0}}
|
||||||
* \parameter{specular\showbreak Transmittance}{\Spectrum\Or\Texture}{Optional
|
* \parameter{specular\showbreak Transmittance}{\Spectrum\Or\Texture}{Optional
|
||||||
* factor used to modulate the transmittance component\default{0.9}}
|
* factor used to modulate the transmittance component\default{1.0}}
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* This plugin implements a realistic microfacet scattering model for rendering
|
* This plugin implements a realistic microfacet scattering model for rendering
|
||||||
|
@ -66,18 +66,14 @@ MTS_NAMESPACE_BEGIN
|
||||||
* these facets, it is possible to reproduce the off-specular reflections
|
* these facets, it is possible to reproduce the off-specular reflections
|
||||||
* peaks observed in measurements of real-world materials.
|
* peaks observed in measurements of real-world materials.
|
||||||
*
|
*
|
||||||
* This plugin is essentially the ``roughened'' equivalent of the
|
* This plugin is essentially the ``roughened'' equivalent of the plugin
|
||||||
* plugin \pluginref{dielectric}. The model supports several types of
|
* \pluginref{dielectric}. Its implementation is based on the paper
|
||||||
* microfacet distributions and a texturable roughness.
|
* ``Microfacet Models for Refraction through Rough Surfaces''
|
||||||
* The default settings are set to a borosilicate glass BK7/air interface
|
* \cite{Walter07Microfacet}. The model supports several types of microfacet
|
||||||
* with a light amount of rougness modeled by a Beckmann distribution.
|
* distributions and a texturable roughness. The default settings are set
|
||||||
*
|
* to a borosilicate glass BK7/air interface with a light amount of rougness
|
||||||
* The implementation is based on the paper ``Microfacet Models for Refraction
|
* modeled using a Beckmann distribution.
|
||||||
* through Rough Surfaces'' \cite{Walter07Microfacet}. It furthermore uses an
|
|
||||||
* improved sampling technique presented in \cite{Zhao11Building} when given
|
|
||||||
* access to an arbitrarily long stream of random numbers.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class RoughGlass : public BSDF {
|
class RoughGlass : public BSDF {
|
||||||
public:
|
public:
|
||||||
//// Microfacet distribution types supported by the model
|
//// Microfacet distribution types supported by the model
|
||||||
|
@ -95,7 +91,7 @@ public:
|
||||||
m_specularReflectance = new ConstantSpectrumTexture(
|
m_specularReflectance = new ConstantSpectrumTexture(
|
||||||
props.getSpectrum("specularReflectance", Spectrum(1.0f)));
|
props.getSpectrum("specularReflectance", Spectrum(1.0f)));
|
||||||
m_specularTransmittance = new ConstantSpectrumTexture(
|
m_specularTransmittance = new ConstantSpectrumTexture(
|
||||||
props.getSpectrum("specularTransmittance", Spectrum(0.9f)));
|
props.getSpectrum("specularTransmittance", Spectrum(1.9f)));
|
||||||
|
|
||||||
Float alpha;
|
Float alpha;
|
||||||
if (props.hasProperty("alphaB")) {
|
if (props.hasProperty("alphaB")) {
|
||||||
|
@ -229,13 +225,13 @@ public:
|
||||||
|
|
||||||
case EGGX: {
|
case EGGX: {
|
||||||
/* Empirical GGX distribution function for rough surfaces */
|
/* Empirical GGX distribution function for rough surfaces */
|
||||||
const Float tanTheta = Frame::tanTheta(m);
|
const Float tanTheta = Frame::tanTheta(m),
|
||||||
const Float cosTheta = Frame::cosTheta(m);
|
cosTheta = Frame::cosTheta(m);
|
||||||
|
|
||||||
const Float root = alpha / (cosTheta*cosTheta *
|
const Float root = alpha / (cosTheta*cosTheta *
|
||||||
(alpha*alpha + tanTheta*tanTheta));
|
(alpha*alpha + tanTheta*tanTheta));
|
||||||
|
|
||||||
result = INV_PI * (root*root);
|
result = INV_PI * (root * root);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -705,12 +705,12 @@ Float fresnel(Float cosThetaI, Float etaExt, Float etaInt) {
|
||||||
Float etaI = etaExt, etaT = etaInt;
|
Float etaI = etaExt, etaT = etaInt;
|
||||||
|
|
||||||
/* Swap the indices of refraction if the interaction starts
|
/* Swap the indices of refraction if the interaction starts
|
||||||
at the inside of the object */
|
at the inside of the object */
|
||||||
if (cosThetaI < 0.0f)
|
if (cosThetaI < 0.0f)
|
||||||
std::swap(etaI, etaT);
|
std::swap(etaI, etaT);
|
||||||
|
|
||||||
/* Using Snell's law, calculate the sine of the angle
|
/* Using Snell's law, calculate the sine of the angle
|
||||||
between the transmitted ray and the surface normal */
|
between the transmitted ray and the surface normal */
|
||||||
Float sinThetaT = etaI / etaT *
|
Float sinThetaT = etaI / etaT *
|
||||||
std::sqrt(std::max((Float) 0.0f, 1.0f - cosThetaI*cosThetaI));
|
std::sqrt(std::max((Float) 0.0f, 1.0f - cosThetaI*cosThetaI));
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,15 @@ MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
GLProgram::GLProgram(const std::string &name)
|
GLProgram::GLProgram(const std::string &name)
|
||||||
: GPUProgram(name) {
|
: GPUProgram(name) {
|
||||||
m_id[0] = m_id[1] = m_program = 0;
|
m_id[EVertexProgram] = 0;
|
||||||
|
m_id[EFragmentProgram] = 0;
|
||||||
|
m_id[EGeometryProgram] = 0;
|
||||||
|
m_program = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLProgram::init() {
|
void GLProgram::init() {
|
||||||
Assert(m_id[0] == 0 && m_id[1] == 0 && m_program == 0);
|
Assert(m_id[EVertexProgram] == 0 && m_id[EFragmentProgram] == 0
|
||||||
|
&& m_id[EGeometryProgram] == 0 && m_program == 0);
|
||||||
|
|
||||||
Log(EDebug, "Uploading a GPU program : %s", toString().c_str());
|
Log(EDebug, "Uploading a GPU program : %s", toString().c_str());
|
||||||
if (!GLEW_ARB_shader_objects)
|
if (!GLEW_ARB_shader_objects)
|
||||||
|
|
|
@ -534,6 +534,7 @@ void GLRenderer::drawAll(const std::vector<std::pair<const GPUGeometry *, Transf
|
||||||
GLRenderer::beginDrawingMeshes(true);
|
GLRenderer::beginDrawingMeshes(true);
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
std::vector<std::pair<const GPUGeometry *, Transform> >::const_iterator it;
|
std::vector<std::pair<const GPUGeometry *, Transform> >::const_iterator it;
|
||||||
if (m_capabilities->isSupported(RendererCapabilities::EBindless)) {
|
if (m_capabilities->isSupported(RendererCapabilities::EBindless)) {
|
||||||
for (it = geo.begin(); it != geo.end(); ++it) {
|
for (it = geo.begin(); it != geo.end(); ++it) {
|
||||||
|
@ -577,7 +578,6 @@ void GLRenderer::drawAll(const std::vector<std::pair<const GPUGeometry *, Transf
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glPopMatrix();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (it = geo.begin(); it != geo.end(); ++it) {
|
for (it = geo.begin(); it != geo.end(); ++it) {
|
||||||
|
@ -616,7 +616,6 @@ void GLRenderer::drawAll(const std::vector<std::pair<const GPUGeometry *, Transf
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glPopMatrix();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GLRenderer::endDrawingMeshes();
|
GLRenderer::endDrawingMeshes();
|
||||||
|
@ -633,6 +632,10 @@ void GLRenderer::blitTexture(const GPUTexture *tex, bool flipVertically,
|
||||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||||
Vector2i scrSize = Vector2i(viewport[2], viewport[3]);
|
Vector2i scrSize = Vector2i(viewport[2], viewport[3]);
|
||||||
Vector2i texSize = Vector2i(tex->getSize().x, tex->getSize().y);
|
Vector2i texSize = Vector2i(tex->getSize().x, tex->getSize().y);
|
||||||
|
if (scrSize.x == 0 || scrSize.y == 0) {
|
||||||
|
tex->unbind();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
|
@ -23,6 +23,11 @@ SceneInformationDialog::SceneInformationDialog(QWidget *parent, Scene *scene) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::SceneInformationDialog) {
|
ui(new Ui::SceneInformationDialog) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
#if defined(__OSX__)
|
||||||
|
QFont font = ui->textEdit->currentFont();
|
||||||
|
font.setPointSize(12);
|
||||||
|
ui->textEdit->setCurrentFont(font);
|
||||||
|
#endif
|
||||||
ui->textEdit->setText(scene->toString().c_str());
|
ui->textEdit->setText(scene->toString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue