pbrt-v4 icon indicating copy to clipboard operation
pbrt-v4 copied to clipboard

Fix NAN bug when MLT propose a path with 0 radiance

Open w3ntao opened this issue 11 months ago • 2 comments

In MLTIntegrator::Render(), when computing radiance for current path and proposed path, there is a non zero probabilty that their radiance (cCurrent, cProposed) evaluated to 0.

In such case, both accept and splat value will be affected:

  • accept will be assigned 1 when cCurrent == 0
  • LProposed * accept / cProposed and LCurrent * (1 - accept) / cCurrent will be evaluated to NAN, thus pollute the final image
Float cProposed = c(LProposed, lambdaProposed);
Float cCurrent = c(LCurrent, lambdaCurrent);
Float accept = std::min<Float>(1, cProposed / cCurrent);

// Splat both current and proposed samples to _film_
if (accept > 0)
    film.AddSplat(pProposed, LProposed * accept / cProposed, lambdaProposed);
film.AddSplat(pCurrent, LCurrent * (1 - accept) / cCurrent, lambdaCurrent);

My proposed fix is simple: just avoid film.AddSplat() when cCurrent == 0 || cProposed == 0, and then compute accept accordingly.

w3ntao avatar Jan 09 '25 07:01 w3ntao

It's not clear to me how this could end up happening: after the bootstrapping step, then by design, every initial path should have a non-zero contribution. As mutations happen, a path with zero contribution should never be accepted. So I'm not sure how we ever end up with cCurrent == 0. Do you have any insight about this? If that is happening, then that suggests there is a bug elsewhere that should probably be found and fixed.

mmp avatar Jan 30 '25 01:01 mmp

after the bootstrapping step, then by design, every initial path should have a non-zero contribution

This is what I disagree: during bootstrapping, when all initial paths carry zero radiance (not so common but I think it's possible), then the importance-sampling-selected path makes zero contribution. That's when you have cCurrent == 0.

w3ntao avatar Feb 08 '25 13:02 w3ntao