From 65952214fe289636f3357b9f2a68c3ab2f265673 Mon Sep 17 00:00:00 2001 From: Wentao Liu <wentao.liu.zero@outlook.com> Date: Thu, 9 Jan 2025 14:32:02 +0800 Subject: [PATCH] Fix NAN bug when MLT propose a path with 0 radiance --- src/pbrt/cpu/integrators.cpp | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/pbrt/cpu/integrators.cpp b/src/pbrt/cpu/integrators.cpp index a8c541f85..2913d49aa 100644 --- a/src/pbrt/cpu/integrators.cpp +++ b/src/pbrt/cpu/integrators.cpp @@ -2679,12 +2679,33 @@ void MLTIntegrator::Render() { // Compute acceptance probability for proposed sample 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); + Float accept = NAN; + if (cProposed == 0 && cCurrent == 0) { + // neither current path or the proposed found a light source + accept = 0.5; + + } else if (cProposed == 0) { + // current path found a light source but the proposed didn't + accept = 0; + film.AddSplat(pCurrent, LCurrent / cCurrent, lambdaCurrent); + + } else if (cCurrent == 0) { + // current path didn't find a light source but the proposed did + accept = 1; + film.AddSplat(pProposed, LProposed / cProposed, lambdaProposed); + + } else { + // both paths found a light source + 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); + } + if (accept < 1) { + film.AddSplat(pCurrent, LCurrent * (1 - accept) / cCurrent, lambdaCurrent); + } + } // Accept or reject the proposal if (rng.Uniform<Float>() < accept) {