improved reliability of specular perturbations
parent
d806c6194e
commit
a279b7f638
|
@ -225,7 +225,7 @@ public:
|
||||||
&& (bRec.component == -1 || bRec.component < (int) m_components.size()-1);
|
&& (bRec.component == -1 || bRec.component < (int) m_components.size()-1);
|
||||||
|
|
||||||
if (measure == EDiscrete && sampleSpecular &&
|
if (measure == EDiscrete && sampleSpecular &&
|
||||||
absDot(reflect(bRec.wi), bRec.wo) > 1-DeltaEpsilon) {
|
std::abs(dot(reflect(bRec.wi), bRec.wo)-1) < DeltaEpsilon) {
|
||||||
return m_specularReflectance->eval(bRec.its) *
|
return m_specularReflectance->eval(bRec.its) *
|
||||||
fresnelDielectricExt(std::abs(Frame::cosTheta(bRec.wi)), m_eta);
|
fresnelDielectricExt(std::abs(Frame::cosTheta(bRec.wi)), m_eta);
|
||||||
} else if (sampleNested) {
|
} else if (sampleNested) {
|
||||||
|
@ -274,7 +274,7 @@ public:
|
||||||
(1-R12) * (1-m_specularSamplingWeight));
|
(1-R12) * (1-m_specularSamplingWeight));
|
||||||
|
|
||||||
if (measure == EDiscrete && sampleSpecular &&
|
if (measure == EDiscrete && sampleSpecular &&
|
||||||
absDot(reflect(bRec.wi), bRec.wo) > 1-DeltaEpsilon) {
|
std::abs(dot(reflect(bRec.wi), bRec.wo)-1) < DeltaEpsilon) {
|
||||||
return sampleNested ? probSpecular : 1.0f;
|
return sampleNested ? probSpecular : 1.0f;
|
||||||
} else if (sampleNested) {
|
} else if (sampleNested) {
|
||||||
Float R21;
|
Float R21;
|
||||||
|
|
|
@ -229,7 +229,7 @@ public:
|
||||||
if (!sampleReflection || measure != EDiscrete ||
|
if (!sampleReflection || measure != EDiscrete ||
|
||||||
Frame::cosTheta(bRec.wi) <= 0 ||
|
Frame::cosTheta(bRec.wi) <= 0 ||
|
||||||
Frame::cosTheta(bRec.wo) <= 0 ||
|
Frame::cosTheta(bRec.wo) <= 0 ||
|
||||||
absDot(reflect(bRec.wi), bRec.wo) < 1-DeltaEpsilon)
|
std::abs(dot(reflect(bRec.wi), bRec.wo)-1) > DeltaEpsilon)
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
return m_specularReflectance->eval(bRec.its) *
|
return m_specularReflectance->eval(bRec.its) *
|
||||||
|
@ -245,7 +245,7 @@ public:
|
||||||
if (!sampleReflection || measure != EDiscrete ||
|
if (!sampleReflection || measure != EDiscrete ||
|
||||||
Frame::cosTheta(bRec.wi) <= 0 ||
|
Frame::cosTheta(bRec.wi) <= 0 ||
|
||||||
Frame::cosTheta(bRec.wo) <= 0 ||
|
Frame::cosTheta(bRec.wo) <= 0 ||
|
||||||
absDot(reflect(bRec.wi), bRec.wo) < 1-DeltaEpsilon)
|
std::abs(dot(reflect(bRec.wi), bRec.wo)-1) > DeltaEpsilon)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
|
|
@ -235,12 +235,12 @@ public:
|
||||||
Float F = fresnelDielectricExt(Frame::cosTheta(bRec.wi), cosThetaT, m_eta);
|
Float F = fresnelDielectricExt(Frame::cosTheta(bRec.wi), cosThetaT, m_eta);
|
||||||
|
|
||||||
if (Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) >= 0) {
|
if (Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) >= 0) {
|
||||||
if (!sampleReflection || absDot(reflect(bRec.wi), bRec.wo) < 1-DeltaEpsilon)
|
if (!sampleReflection || std::abs(dot(reflect(bRec.wi), bRec.wo)-1) > DeltaEpsilon)
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
return m_specularReflectance->eval(bRec.its) * F;
|
return m_specularReflectance->eval(bRec.its) * F;
|
||||||
} else {
|
} else {
|
||||||
if (!sampleTransmission || absDot(refract(bRec.wi, cosThetaT), bRec.wo) < 1-DeltaEpsilon)
|
if (!sampleTransmission || std::abs(dot(refract(bRec.wi, cosThetaT), bRec.wo)-1) > DeltaEpsilon)
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
/* Radiance must be scaled to account for the solid angle compression
|
/* Radiance must be scaled to account for the solid angle compression
|
||||||
|
@ -262,12 +262,12 @@ public:
|
||||||
Float F = fresnelDielectricExt(Frame::cosTheta(bRec.wi), cosThetaT, m_eta);
|
Float F = fresnelDielectricExt(Frame::cosTheta(bRec.wi), cosThetaT, m_eta);
|
||||||
|
|
||||||
if (Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) >= 0) {
|
if (Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) >= 0) {
|
||||||
if (!sampleReflection || absDot(reflect(bRec.wi), bRec.wo) < 1-DeltaEpsilon)
|
if (!sampleReflection || std::abs(dot(reflect(bRec.wi), bRec.wo)-1) > DeltaEpsilon)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
return sampleTransmission ? F : 1.0f;
|
return sampleTransmission ? F : 1.0f;
|
||||||
} else {
|
} else {
|
||||||
if (!sampleTransmission || absDot(refract(bRec.wi, cosThetaT), bRec.wo) < 1-DeltaEpsilon)
|
if (!sampleTransmission || std::abs(dot(refract(bRec.wi, cosThetaT), bRec.wo)-1) > DeltaEpsilon)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
return sampleReflection ? 1-F : 1.0f;
|
return sampleReflection ? 1-F : 1.0f;
|
||||||
|
|
|
@ -255,7 +255,7 @@ public:
|
||||||
if (hasSpecular) {
|
if (hasSpecular) {
|
||||||
/* Check if the provided direction pair matches an ideal
|
/* Check if the provided direction pair matches an ideal
|
||||||
specular reflection; tolerate some roundoff errors */
|
specular reflection; tolerate some roundoff errors */
|
||||||
if (absDot(reflect(bRec.wi), bRec.wo) > 1-DeltaEpsilon)
|
if (std::abs(dot(reflect(bRec.wi), bRec.wo)-1) < DeltaEpsilon)
|
||||||
return m_specularReflectance->eval(bRec.its) * Fi;
|
return m_specularReflectance->eval(bRec.its) * Fi;
|
||||||
} else if (hasDiffuse) {
|
} else if (hasDiffuse) {
|
||||||
Float Fo = fresnelDielectricExt(Frame::cosTheta(bRec.wo), m_eta);
|
Float Fo = fresnelDielectricExt(Frame::cosTheta(bRec.wo), m_eta);
|
||||||
|
@ -294,7 +294,7 @@ public:
|
||||||
if (hasSpecular && measure == EDiscrete) {
|
if (hasSpecular && measure == EDiscrete) {
|
||||||
/* Check if the provided direction pair matches an ideal
|
/* Check if the provided direction pair matches an ideal
|
||||||
specular reflection; tolerate some roundoff errors */
|
specular reflection; tolerate some roundoff errors */
|
||||||
if (absDot(reflect(bRec.wi), bRec.wo) > 1-DeltaEpsilon)
|
if (std::abs(dot(reflect(bRec.wi), bRec.wo)-1) < DeltaEpsilon)
|
||||||
return probSpecular;
|
return probSpecular;
|
||||||
} else if (hasDiffuse && measure == ESolidAngle) {
|
} else if (hasDiffuse && measure == ESolidAngle) {
|
||||||
return Warp::squareToCosineHemispherePdf(bRec.wo) * (1-probSpecular);
|
return Warp::squareToCosineHemispherePdf(bRec.wo) * (1-probSpecular);
|
||||||
|
|
|
@ -163,12 +163,12 @@ public:
|
||||||
R += T*T * R / (1-R*R);
|
R += T*T * R / (1-R*R);
|
||||||
|
|
||||||
if (Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) >= 0) {
|
if (Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) >= 0) {
|
||||||
if (!sampleReflection || absDot(reflect(bRec.wi), bRec.wo) < 1-DeltaEpsilon)
|
if (!sampleReflection || std::abs(dot(reflect(bRec.wi), bRec.wo)-1) > DeltaEpsilon)
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
return m_specularReflectance->eval(bRec.its) * R;
|
return m_specularReflectance->eval(bRec.its) * R;
|
||||||
} else {
|
} else {
|
||||||
if (!sampleTransmission || absDot(transmit(bRec.wi), bRec.wo) < 1-DeltaEpsilon)
|
if (!sampleTransmission || std::abs(dot(transmit(bRec.wi), bRec.wo)-1) > DeltaEpsilon)
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
return m_specularTransmittance->eval(bRec.its) * (1 - R);
|
return m_specularTransmittance->eval(bRec.its) * (1 - R);
|
||||||
|
@ -188,12 +188,12 @@ public:
|
||||||
R += T*T * R / (1-R*R);
|
R += T*T * R / (1-R*R);
|
||||||
|
|
||||||
if (Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) >= 0) {
|
if (Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) >= 0) {
|
||||||
if (!sampleReflection || absDot(reflect(bRec.wi), bRec.wo) < 1-DeltaEpsilon)
|
if (!sampleReflection || std::abs(dot(reflect(bRec.wi), bRec.wo)-1) > DeltaEpsilon)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
return sampleTransmission ? R : 1.0f;
|
return sampleTransmission ? R : 1.0f;
|
||||||
} else {
|
} else {
|
||||||
if (!sampleTransmission || absDot(transmit(bRec.wi), bRec.wo) < 1-DeltaEpsilon)
|
if (!sampleTransmission || std::abs(dot(transmit(bRec.wi), bRec.wo)-1) > DeltaEpsilon)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
return sampleReflection ? 1-R : 1.0f;
|
return sampleReflection ? 1-R : 1.0f;
|
||||||
|
|
|
@ -710,7 +710,13 @@ bool PathVertex::propagatePerturbation(const Scene *scene, const PathVertex *pre
|
||||||
|
|
||||||
bRec.typeMask = BSDF::EAll;
|
bRec.typeMask = BSDF::EAll;
|
||||||
Float prob = bsdf->pdf(bRec, EDiscrete);
|
Float prob = bsdf->pdf(bRec, EDiscrete);
|
||||||
weight[mode] = bsdf->eval(bRec, EDiscrete)/prob;
|
if (prob == 0) {
|
||||||
|
SLog(EWarn, "Unable to recreate specular vertex in perturbation (bsdf=%s)",
|
||||||
|
bsdf->toString().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
weight[mode] = bsdf->eval(bRec, EDiscrete) / prob;
|
||||||
pdf[mode] = prob;
|
pdf[mode] = prob;
|
||||||
measure = EDiscrete;
|
measure = EDiscrete;
|
||||||
componentType = componentType_;
|
componentType = componentType_;
|
||||||
|
|
Loading…
Reference in New Issue