PLTFalcor
PLTFalcor copied to clipboard
Question Regarding Path Weight Update Order in `scatterTriangleMeshClosestHit` Shader
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;
https://github.com/ssteinberg/PLTFalcor/blob/6c58971d1f8f031eb61ce8fd93e4ffddbe963e85/Source/RenderPasses/PLTPT/pltpt_sample.rt.slang#L130
Understanding of the Implementation:
appendBounceregisters 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
pis passed toNEE()andevalEmissive():- https://github.com/ssteinberg/PLTFalcor/blob/6c58971d1f8f031eb61ce8fd93e4ffddbe963e85/Source/RenderPasses/PLTPT/pltpt_solve.rt.slang#L421
- https://github.com/ssteinberg/PLTFalcor/blob/6c58971d1f8f031eb61ce8fd93e4ffddbe963e85/Source/RenderPasses/PLTPT/pltpt_solve.rt.slang#L441
- https://github.com/ssteinberg/PLTFalcor/blob/6c58971d1f8f031eb61ce8fd93e4ffddbe963e85/Source/RenderPasses/PLTPT/pltpt_solve.rt.slang#L446
- The bounce contribution used is that of bounce
p:- For
NEE: https://github.com/ssteinberg/PLTFalcor/blob/6c58971d1f8f031eb61ce8fd93e4ffddbe963e85/Source/RenderPasses/PLTPT/pltpt_solve.rt.slang#L242 - For
evalEmissive: https://github.com/ssteinberg/PLTFalcor/blob/6c58971d1f8f031eb61ce8fd93e4ffddbe963e85/Source/RenderPasses/PLTPT/pltpt_solve.rt.slang#L197
- For
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
maxBouncesto 0 triggersshouldEndPath, skipping the multiplication bybsdfSample.pdf: https://github.com/ssteinberg/PLTFalcor/blob/6c58971d1f8f031eb61ce8fd93e4ffddbe963e85/Source/RenderPasses/PLTPT/pltpt_sample.rt.slang#L114 - The resulting output is extremely dim.
- Increasing
maxBouncesto 1 includes the multiplication, and the result is noticeably brighter. - Image Illustrating the Issue:
- Setting
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.weightbefore appending the bounce, resulting in the inclusion ofbsdfSample.pdfin the current bounce's contribution? - Could updating
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? - If updating
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.
That's likely wrong. Not sure why it was done so. Thanks for noticing. This project is not maintained, but I will leave this open in case anyone else stumbles upon this.