Hello!
I've been studying your work on Physical Light Transport and, more recently, this implementation. Thank you for sharing it with the community.
I'm encountering a potential issue with the order in which path.weight is updated relative to appending bounces in the scatterTriangleMeshClosestHit shader. This affects the weighting of bounce contributions during Next Event Estimation (NEE) and emissive evaluations.
Current Implementation:
In the scatterTriangleMeshClosestHit function, the path weight is updated after BSDF sampling and before appending the bounce:
// BSDF sampling and generate a new ray direction.
BSDFSample bsdfSample;
if (!shouldEndPath) {
// BSDF sampling logic...
}
// Update path weight, thp, and pdf
path.weight *= bsdfSample.weight;
path.thp_modifier *= rcp_thp;
path.pdf *= bsdfSample.pdf;
// Append bounce
appendBounce(path, hitInfo, wi, bsdfSample.lobe);
++path.length;
|
appendBounce(path, hitInfo, wi, bsdfSample.lobe); |
Understanding of the Implementation:
appendBounce registers the path contribution as the bounce contribution.
- This bounce contribution is used in the solve step to weigh the sample's contribution.
- In the solve functions, during path traversal, the current bounce
p is passed to NEE() and evalEmissive():
|
const BounceData bounce = readBounce(p, pixel); |
|
NEE(solveData, p, bounce, pixel, triangleHit, sd, v, bsdf, bsdfProp); |
|
evalEmissive(solveData, p, bounce, pixel, bsdf, bsdfProp, sd, triangleHit, importanceSampleSpectrum); |
- The bounce contribution used is that of bounce
p:
- For
NEE:
|
measure(solveData, bounceIdx, bounce.pathContribution, beam); |
- For
evalEmissive:
|
measure(solveData, bounceIdx, bounce.pathContribution, beam); |
Issue Description:
Because path.weight is updated before appending the bounce, the bounce's contribution already includes the bsdfSample.pdf of the next direction. This inclusion seems incorrect because the bsdfSample.pdf relates to the sampling of the next direction, not the current one. As a result, during NEE and emissive evaluations at the current bounce, the contributions are weighted by an unrelated probability, potentially leading to inaccurate results.
Expected Behavior:
The bounce contribution used during NEE and emissive evaluations should not include the new direction's bsdfSample.pdf, as it pertains to the next path segment, not the current one.
Observed Behavior:
- In a simple scene with a sun analytic light and spheres with different materials (roughness set to 1.0):
- Setting
maxBounces to 0 triggers shouldEndPath, skipping the multiplication by bsdfSample.pdf:
- The resulting output is extremely dim.
- Increasing
maxBounces to 1 includes the multiplication, and the result is noticeably brighter.
- Image Illustrating the Issue:

Theoretical Concern:
Multiplying the contribution by bsdfSample.pdf results in an estimator that divides by an unrelated probability( $p_b(x_{3,i} | x_1)$ ), which should be incorrect. The estimator for Direct Light Sampling under NEE would effectively become:
$$
L' = \frac{1}{N} \sum_{i=1}^{N} \frac{L_e(x_{2,i} \rightarrow x_1) \cdot f(x_1, \omega_1, \omega_{2,i}) \cdot G(x_1 \leftrightarrow x_{2,i}) \cdot V(x_1, x_{2,i})}{p_l(x_{2,i} | x_1) \cdot p_b(x_{3,i} | x_1)} \frac{p_l(x_{2,i} | x_1)}{p_l(x_{2,i} | x_1) + p_b(x_{2,i} | x_1)}
$$
with
-
$p_l(x | x_1)$ the probability of sampling $x$ given $x_1$ under direct light sampling
-
$p_b(x | x_1)$ the probability of sampling $x$ given $x_1$ under bsdf sampling
This suggests that the bsdfSample.pdf of a different direction influences the current bounce's contribution.
Question:
- Is there a specific reason for updating
path.weight before appending the bounce, resulting in the inclusion of bsdfSample.pdf in the current bounce's contribution?
- Could updating
path.weight after appending the bounce be more appropriate to ensure that only relevant probabilities influence the current bounce's contribution during NEE and emissive evaluations?
- If updating
path.weight after appending the bounce is more appropriate to exclude the unrelated bsdfSample.pdf, why does this change result in the image appearing so dim? Is there an aspect of the implementation or theory I'm missing that could explain this behavior?
Thank you very much for your assistance. I appreciate any insights you can give me.
Hello!
I've been studying your work on Physical Light Transport and, more recently, this implementation. Thank you for sharing it with the community.
I'm encountering a potential issue with the order in which
path.weightis updated relative to appending bounces in thescatterTriangleMeshClosestHitshader. This affects the weighting of bounce contributions during Next Event Estimation (NEE) and emissive evaluations.Current Implementation:
In the
scatterTriangleMeshClosestHitfunction, the path weight is updated after BSDF sampling and before appending the bounce:PLTFalcor/Source/RenderPasses/PLTPT/pltpt_sample.rt.slang
Line 130 in 6c58971
Understanding of the Implementation:
appendBounceregisters the path contribution as the bounce contribution.pis passed toNEE()andevalEmissive():PLTFalcor/Source/RenderPasses/PLTPT/pltpt_solve.rt.slang
Line 421 in 6c58971
PLTFalcor/Source/RenderPasses/PLTPT/pltpt_solve.rt.slang
Line 441 in 6c58971
PLTFalcor/Source/RenderPasses/PLTPT/pltpt_solve.rt.slang
Line 446 in 6c58971
p:NEE:PLTFalcor/Source/RenderPasses/PLTPT/pltpt_solve.rt.slang
Line 242 in 6c58971
evalEmissive:PLTFalcor/Source/RenderPasses/PLTPT/pltpt_solve.rt.slang
Line 197 in 6c58971
Issue Description:
Because
path.weightis updated before appending the bounce, the bounce's contribution already includes thebsdfSample.pdfof the next direction. This inclusion seems incorrect because thebsdfSample.pdfrelates to the sampling of the next direction, not the current one. As a result, during NEE and emissive evaluations at the current bounce, the contributions are weighted by an unrelated probability, potentially leading to inaccurate results.Expected Behavior:
The bounce contribution used during NEE and emissive evaluations should not include the new direction's
bsdfSample.pdf, as it pertains to the next path segment, not the current one.Observed Behavior:
maxBouncesto 0 triggersshouldEndPath, skipping the multiplication bybsdfSample.pdf:PLTFalcor/Source/RenderPasses/PLTPT/pltpt_sample.rt.slang
Line 114 in 6c58971
maxBouncesto 1 includes the multiplication, and the result is noticeably brighter.Theoretical Concern:
Multiplying the contribution by$p_b(x_{3,i} | x_1)$ ), which should be incorrect. The estimator for Direct Light Sampling under NEE would effectively become:
bsdfSample.pdfresults in an estimator that divides by an unrelated probability(with
This suggests that the
bsdfSample.pdfof a different direction influences the current bounce's contribution.Question:
path.weightbefore appending the bounce, resulting in the inclusion ofbsdfSample.pdfin the current bounce's contribution?path.weightafter appending the bounce be more appropriate to ensure that only relevant probabilities influence the current bounce's contribution during NEE and emissive evaluations?path.weightafter appending the bounce is more appropriate to exclude the unrelatedbsdfSample.pdf, why does this change result in the image appearing so dim? Is there an aspect of the implementation or theory I'm missing that could explain this behavior?Thank you very much for your assistance. I appreciate any insights you can give me.