up to Schedule & Notes

Bias in Ray Tracing

We could ray trace until the number of bounces is greater than some constant, $k$.

Better would be to weight each ray by its expected contribution to the pixel from which it originated.

Recall that the recursive ray is sent in the ideal specular reflection and collects some amount of light, $I_\mathrm{in}$. That light goes through the specular part of the Phong equation to get $$\begin{array}{ll} I_\mathrm{out} = k_s\ (R \cdot V)^n\ I_\mathrm{in} \\ I_\mathrm{out} = k_s\ I_\mathrm{in} & \textrm{since } R \cdot V = 1 \end{array}$$

For a whole chain of recursive bounces with specular coefficients $k_1, k_2, \ldots$, we have

So the weight of a ray is $$\displaystyle w = {\prod_{i=1}^n}\ k_i$$ for the $n$ specular coefficients, $k_1, k_2, \ldots, k_n$ on its path back to the eye.

The weight, $w$, is the factor by which any light found on this ray will be attenuated before it contributes to the originating pixel.

Idea: Terminate the ray after $w \lt \tau$ for threshold, $\tau$, like 0.01.

This is good because we will trace rays that provide important contributions, and discard those that don't.

This is bad because this introduces a bias toward a darker-than-actual image, since we're always missing a tiny bit of light at the end of each ray.

Russian Roulette

The bias problem can be solved with a technique called Russian Roulette.

Let $w^* = \prod_{i=1}^n k_i$, which is what the weight that a ray should be.

Let $w$ be the actual weight of a ray used in the ray tracing calculation.

At a bounce:

If $w^* \ge \tau$, the ray continues and has weight $w = w^*$.

If $w^* \lt \tau$, the ray is terminated and its actual weight becomes $w = 0$ since it will not be used in the ray tracing calculation.

The expected value, $E(v)$, of a variable, $v$, is its average value over all possible situations.

If $E(w) = w^*$ then, on average, the ray has the right weight and, with many rays, we get the correct amount of light in the pixel.

If $E(w) \lt w^*$, as it is when rays get terminated as described above, then, on average, the ray has too little weight and, with many rays, we get too little light in the pixel.

But we cannot let rays go on forever. So how do we terminate rays but still get $E(w) = w^*$, so the pixel has the right amount of light?

Idea: Terminate the ray probabilistically. After a bounce:

If we do that, the expected value of $w$ after a possible termination is $$\begin{array}{rcl} E(w) &=& P(\textrm{survival}) \times \textrm{weight } w \textrm{ upon survival} + P(\textrm{termination}) \times \textrm{weight } w \textrm{ upon termination} \\ &=& (1-p) \times {1 \over 1-p} w^* + p \times 0 \\ &=& w^* \end{array}$$

This method causes the expected weight of each ray to be the correct weight, $w^*$, so there is no bias in the amount of light arriving at a pixel.

When implementing, we have to keep track of the "reweighting factor", ${1 \over 1-p}$, at each bounce and apply that factor to any light returning along the recursive ray, which survived termination.

up to Schedule & Notes