Success! The short version is that there's a subtle bug in the
specular transmission code that leads to not-a-number values when the
incident ray is in the plane of the refractive object. (This happens
surprisingly often in the plants scene!). I don't know why things
went particularly bad with the 64-bit build, but it's nice that the
long-lurking problem manifested itself more obviously.
I've pushed an updated version of the minor changes up to the git
repository (available from
http://github.com/mmp/pbrt-v1/tree). I've
also tarred up everything; grab
http://pbrt.org/src/pbrt-1.05-
rc1.tar.gz. (This will eventually turn into the 1.05 release of pbrt.)
Sorry for the bother.. Beyond some added infrastructure for new
assertions to catch such bugs earlier, the main changes are pretty
simple (diffs inline below, FWIW).
Thanks,
-matt
diff --git a/core/reflection.cpp b/core/reflection.cpp
index 8257221..b14eb01 100644
--- a/core/reflection.cpp
+++ b/core/reflection.cpp
@@ -84,7 +84,7 @@ Spectrum FresnelDielectric::Evaluate(float cosi)
const {
swap(ei, et);
// Compute _sint_ using Snell's law
float sint = ei/et * sqrtf(max(0.f, 1.f - cosi*cosi));
- if (sint > 1.) {
+ if (sint >= 1.) {
// Handle total internal reflection
return 1.;
}
@@ -113,7 +113,7 @@ Spectrum SpecularTransmission::Sample_f(const
Vector &wo,
float eta = ei / et;
float sint2 = eta * eta * sini2;
// Handle total internal reflection for transmission
- if (sint2 > 1.) return 0.;
+ if (sint2 >= 1.) return 0.;
float cost = sqrtf(max(0.f, 1.f - sint2));
if (entering) cost = -cost;
float sintOverSini = eta;
diff --git a/core/util.cpp b/core/util.cpp
index cf439c4..0f3f8ec 100644
--- a/core/util.cpp
+++ b/core/util.cpp
@@ -65,7 +65,7 @@ static void processError(const char *format, va_list
args,
fprintf(stderr, "\tLine %d, file %s\n",
line_num,
current_file.c_str());
}
- exit(1);
+ abort();
}
#ifndef WIN32
free(errorBuf);
diff --git a/integrators/directlighting.cpp b/integrators/
directlighting.cpp
index 53ff788..db60f9c 100644
--- a/integrators/directlighting.cpp
+++ b/integrators/directlighting.cpp
@@ -129,7 +129,7 @@ Spectrum DirectLighting::Li(const Scene *scene,
// Trace rays for specular reflection and
refraction
Spectrum f = bsdf->Sample_f(wo, &wi,
BxDFType(BSDF_REFLECTION |
BSDF_SPECULAR));
- if (!f.Black()) {
+ if (!f.Black() && AbsDot(wi, n) > 0.f) {
// Compute ray differential _rd_ for
specular reflection
RayDifferential rd(p, wi);
rd.hasDifferentials = true;
@@ -153,7 +153,7 @@ Spectrum DirectLighting::Li(const Scene *scene,
}
f = bsdf->Sample_f(wo, &wi,
BxDFType(BSDF_TRANSMISSION |
BSDF_SPECULAR));
- if (!f.Black()) {
+ if (!f.Black() && AbsDot(wi, n) > 0.f) {
// Compute ray differential _rd_ for
specular transmission
RayDifferential rd(p, wi);
rd.hasDifferentials = true;
diff --git a/integrators/irradiancecache.cpp b/integrators/
irradiancecache.cpp
index af85eaf..a089554 100644
--- a/integrators/irradiancecache.cpp
+++ b/integrators/irradiancecache.cpp
@@ -136,7 +136,7 @@ Spectrum IrradianceCache::Li(const Scene *scene,
const RayDifferential &ray,
// Trace rays for specular reflection and
refraction
Spectrum f = bsdf->Sample_f(wo, &wi,
BxDFType(BSDF_REFLECTION |
BSDF_SPECULAR));
- if (!f.Black()) {
+ if (!f.Black() && AbsDot(wi, n) > 0.f) {
// Compute ray differential _rd_ for
specular reflection
RayDifferential rd(p, wi);
rd.hasDifferentials = true;
@@ -160,7 +160,7 @@ Spectrum IrradianceCache::Li(const Scene *scene,
const RayDifferential &ray,
}
f = bsdf->Sample_f(wo, &wi,
BxDFType(BSDF_TRANSMISSION |
BSDF_SPECULAR));
- if (!f.Black()) {
+ if (!f.Black() && AbsDot(wi, n) > 0.f) {
// Compute ray differential _rd_ for
specular transmission
RayDifferential rd(p, wi);
rd.hasDifferentials = true;
diff --git a/integrators/photonmap.cpp b/integrators/photonmap.cpp
index 454aa43..0c77c87 100644
--- a/integrators/photonmap.cpp
+++ b/integrators/photonmap.cpp
@@ -367,7 +367,7 @@ Spectrum PhotonIntegrator::Li(const Scene *scene,
// Trace rays for specular reflection and
refraction
Spectrum f = bsdf->Sample_f(wo, &wi,
BxDFType(BSDF_REFLECTION |
BSDF_SPECULAR));
- if (!f.Black()) {
+ if (!f.Black() && AbsDot(wi, n) > 0.f) {
// Compute ray differential _rd_ for
specular reflection
RayDifferential rd(p, wi);
rd.hasDifferentials = true;
@@ -391,7 +391,7 @@ Spectrum PhotonIntegrator::Li(const Scene *scene,
}
f = bsdf->Sample_f(wo, &wi,
BxDFType(BSDF_TRANSMISSION |
BSDF_SPECULAR));
- if (!f.Black()) {
+ if (!f.Black() && AbsDot(wi, n) > 0.f) {
// Compute ray differential _rd_ for
specular transmission
RayDifferential rd(p, wi);
rd.hasDifferentials = true;
diff --git a/integrators/whitted.cpp b/integrators/whitted.cpp
index 7024b89..6a87a16 100644
--- a/integrators/whitted.cpp
+++ b/integrators/whitted.cpp
@@ -83,7 +83,7 @@ Spectrum WhittedIntegrator::Li(const Scene *scene,
// Trace rays for specular reflection and
refraction
Spectrum f = bsdf->Sample_f(wo, &wi,
BxDFType(BSDF_REFLECTION |
BSDF_SPECULAR));
- if (!f.Black()) {
+ if (!f.Black() && AbsDot(wi, n) > 0.f) {
// Compute ray differential _rd_ for
specular reflection
RayDifferential rd(p, wi);
rd.hasDifferentials = true;
@@ -107,7 +107,7 @@ Spectrum WhittedIntegrator::Li(const Scene *scene,
}
f = bsdf->Sample_f(wo, &wi,
BxDFType(BSDF_TRANSMISSION |
BSDF_SPECULAR));
- if (!f.Black()) {
+ if (!f.Black() && AbsDot(wi, n) > 0.f) {
// Compute ray differential _rd_ for
specular transmission
RayDifferential rd(p, wi);
rd.hasDifferentials = true;