<p>The code does seem a bit ugly since it doesn't assign pdf and instead returns 0.</p>

<p>By returning 0 it's basically saying the same thing as pdf = 0 because <code>f.IsBlack()</code> returns true.</p>

<p>This is acceptable, it's basically saying the BSDF doesn't allow light go through at the given <span class="math-container">$w_o$</span></p>

CC BY-SA 4.0
2018-12-02T04:36:05.500Z
2018-12-02T04:36:05.500Z
Calvin
<p>I've been implementing a path tracer, referring pbrt-v3. However, I'm a bit confused about its implementation. Code is <a href="https://github.com/mmp/pbrt-v3/blob/9f717d847a807793fa966cf0eaa366852efef167/src/core/reflection.cpp#L477" rel="nofollow noreferrer">here</a>.</p>

<p>It seems when we sample to do transmission, it tests if it meets a total internal reflection, but it doesn't assign a proper value to the <code>pdf</code>, instead, after the function returns <code>Vec3f(0,0,0)</code> as BTDF value, it then tests if <code>pdf</code> is 0, if 0 then directly jumps out of the tracing loop.</p>

<p>I don't think this make sense since there should be radiance value if this ray continues to trace and does out of the specular object and hit a surface which is illuminated. But this implementation seems to leave out all such kind of radiance, and rely on the <code>sample_f</code> function to sample a reflection.</p>

<p>So how to properly compute the <code>pdf</code> of total internal reflection?</p>

<pre><code>        // Account for the indirect subsurface scattering component
        Spectrum f = pi.bsdf-&gt;Sample_f(pi.wo, &amp;wi, sampler.Get2D(), &amp;pdf,
                                       BSDF_ALL, &amp;flags);
        if (f.IsBlack() || pdf == 0) break;
</code></pre>

<pathtracing><brdf><physically-based><specular><reflection>
total internal reflection implementation in pbrt-v3
jinglei
# total internal reflection implementation in pbrt-v3

(Asked by: username_0 on 2018-11-19)

I've been implementing a path tracer, referring pbrt-v3. However, I'm a bit confused about its implementation. Code is [here](https://github.com/mmp/pbrt-v3/blob/9f717d847a807793fa966cf0eaa366852efef167/src/core/reflection.cpp#L477).

It seems when we sample to do transmission, it tests if it meets a total internal reflection, but it doesn't assign a proper value to the `pdf`, instead, after the function returns `Vec3f(0,0,0)` as BTDF value, it then tests if `pdf` is 0, if 0 then directly jumps out of the tracing loop.

I don't think this make sense since there should be radiance value if this ray continues to trace and does out of the specular object and hit a surface which is illuminated. But this implementation seems to leave out all such kind of radiance, and rely on the `sample_f` function to sample a reflection.

So how to properly compute the `pdf` of total internal reflection?

```
        // Account for the indirect subsurface scattering component
        Spectrum f = pi.bsdf->Sample_f(pi.wo, &wi, sampler.Get2D(), &pdf,
                                       BSDF_ALL, &flags);
        if (f.IsBlack() || pdf == 0) break;

```

**Tags:** pathtracing, brdf, physically-based, specular, reflection


---

## 1 answers

### Answer by username_1 on 2018-12-02. Score: 1

The code does seem a bit ugly since it doesn't assign pdf and instead returns 0.

By returning 0 it's basically saying the same thing as pdf = 0 because `f.IsBlack()` returns true.

This is acceptable, it's basically saying the BSDF doesn't allow light go through at the given $w\_o$


---

