### Russian Roulette for terminating volumetric ray marching?

Posted:

**Fri Feb 13, 2015 3:30 pm**Hello,

I have a question about how to implement Russian Roulette termination while marching a ray through a volume and accumulating transmittance.

The only example I've found on how to implement this is in the Physically Based Rendering book. In there, the following code snippet is included in the ray marching loop:

The way I understand Russian Roulette, there is some expensive computation F that we wish to perform only with probability q, otherwise F is replaced by some value c (usually zero). For the

expected value to stay the same, however, in those cases where we choose to compute F, it needs to be transformed into F' = (F - qc)/(1-q).

In the code above, when we choose to terminate, we break out of the loop so the output transmittance is the transmittance Tr up to the termination point. In that case, c = Tr: the value we wish to use instead of F (the full ray marching solution with no early terminations) and the line
cannot be correct. For that update to be correct, it would have to be c = 0, in which case the code would be:

This modified version does not seem very helpful because, as one keeps marching along the ray, so many 50/50 coin tosses are taken that inevitably the ray will be terminated and the transmittance will come out zero, except in a few very rare cases where all consecutive coin tosses come up the same way.

I would appreciate if anyone could elucidate me on this. I'm sure the Pharr & Humphreys implementation is correct, I'm just not being able to work out the maths in my head.

Thanks,

manuel

I have a question about how to implement Russian Roulette termination while marching a ray through a volume and accumulating transmittance.

The only example I've found on how to implement this is in the Physically Based Rendering book. In there, the following code snippet is included in the ray marching loop:

Code: Select all

```
// Possibly terminate ray marching if transmittance is small
if (Tr.y() < 1e-3) {
const float continueProb = .5f;
if (rng.RandomFloat() > continueProb) break;
Tr /= continueProb;
}
```

expected value to stay the same, however, in those cases where we choose to compute F, it needs to be transformed into F' = (F - qc)/(1-q).

In the code above, when we choose to terminate, we break out of the loop so the output transmittance is the transmittance Tr up to the termination point. In that case, c = Tr: the value we wish to use instead of F (the full ray marching solution with no early terminations) and the line

Code: Select all

```
Tr /= continueProb
```

Code: Select all

```
if (Tr.y() < 1e-3) {
const float continueProb = .5f;
if (rng.RandomFloat() > continueProb)
{
Tr = 0;
break;
}
Tr /= continueProb;
}
```

I would appreciate if anyone could elucidate me on this. I'm sure the Pharr & Humphreys implementation is correct, I'm just not being able to work out the maths in my head.

Thanks,

manuel