# Choosing Reflection or Refraction in Path Tracing

I am trying to implement refraction and transmission in my path tracer and I'm a bit unsure on how to implement it. First, some background:

When light hits a surface, a portion of it will reflect, and a portion will be refracted: How much light reflects vs. refracts is given by the Fresnel Equations In a recursive ray tracer, the simple implementation would be to shoot a ray for reflection and a ray for refraction, then do a weighted sum using the Fresnel. \begin{align*} R &= Fresnel()\\ T &= 1 - R\\ L_{\text{o}} &= R \cdot L_{\text{i,reflection}} + T \cdot L_{\text{i,refraction}} \end{align*}

However, in path tracing, we only choose one path. This is my question:

• How do I choose whether to reflect or refract in a non-biased way

My first guess would be to randomly choose based on the Fresnel. Aka:

float p = randf();
float fresnel = Fresnel();
if (p <= fresnel) {
// Reflect
} else {
// Refract
}


Would this be correct? Or do I need to have some kind of correction factor? Since I'm not taking both paths.

• russian roulette May 30 '16 at 1:46

## TL;DR

Yes, you can do it like that, you just have to divide the result by the probability of choosing the direction.

The topic of sampling in path tracers allowing materials with both reflection and refraction is actually a little bit more complex.

Let's start with some background first. If you allow BSDFs - not just BRDFs - in your path tracer, you have to integrate over the whole sphere instead of just the positive hemisphere. Monte Carlo samples can be generated by various strategies: for the direct illumination you can use BSDF and light sampling, for the indirect illumination the only meaningful strategy usually is the BSDF sampling. The sampling strategies themselves usually contain the decision about which hemisphere to sample (e.g. whether reflection or refraction is computed).

In the simplest version, the light sampling usually doesn't take care much about reflection or refraction. It samples the light sources or the environment map (if present) with respect to the light properties. You can improve sampling of environment maps by picking just the hemisphere in which the material has non-zero contribution, but the rest of the material properties is usually ignored. Note that for and ideally smooth Fresnel material the light sampling doesn't work.

For BSDF sampling, the situation is much more interesting. The case you described deals with an ideal Fresnel surface, where there are only two contributing directions (since Fresnel BSDF is in fact just a sum of two delta functions). You can easily split the integral into a sum of two parts - one reflection and one for refraction. Since, as you mentioned, we don’t want to go in both directions in a path tracer, we have to pick one. This means that we want to estimate the sum of numbers by picking just one of them. This can be done by discrete Monte Carlo estimation: pick one of the addends randomly and divide it by the probability of it being picked. In an ideal case you want to have the sampling probability proportional the the addends, but since we don't know their values (we wouldn't have to estimate the sum if we knew them), we just estimate them by neglecting some of the factors. In this case, we ignore the incoming light amount and use just the Fresnel reflectance/transmittance as our estimates.

The BSDF sampling routine for the case of smooth Fresnel surface is, therefore, to pick one of the directions randomly with probability proportional to the the Fresnel reflectance and, at some point, divide the result for that direction by probability of picking the direction. The estimator will look like:

$$\frac {L_{i}\left(\omega_{i}\right)F\left(\theta_{i}\right)} {P\left(\omega_{i}\right)} = \frac {L_{i}\left(\omega_{i}\right)F\left(\theta_{i}\right)} {F\left(\theta_{i}\right)} = L_{i}\left(\omega_{i}\right)$$

Where $\omega_{i}=\left( \phi_{i}, \theta_{i} \right)$ is the chosen incident light direction, $L_{i}\left(\omega_{i}\right)$ is the amount of incident radiance, $F\left(\theta_{i}\right)$ is either the Fresnel reflectance for the reflection case or 1 - Fresnel reflectance for the refraction case, $P\left(\omega_{i}\right)$ is the discrete probability of picking the direction and is equal to $F\left(\theta_{i}\right)$.

In case of more sophisticated BSDF models like those based on microfacet theory, the sampling is slightly more complex, but the idea of splitting the whole integral into a finite sum of sub-integrals and using discrete Monte Carlo afterwards can usually be applied too.

• This is interesting but I'm confused by one point. Could you clarify what it means to "divide the result for that direction by probability of picking the direction"? If it is not a binary choice but a direction chosen from a continuous distribution, won't the probability be zero? May 23 '16 at 15:00
• @trichoplax: Yes it would, but in that paragraph I was describing the sampling technique just for a (dielectric) Fresnel BSDF - ideally smooth surface, which is a sum of two Dirac delta functions. In such case you are picking one of the directions with some discrete probability. In case of a non-delta (finite) BSDF, you generate directions according to a probability density function. Unfortunately, delta and non-delta cases have to be handled separately, which makes the code a little messy. More details on sampling microfacet BSDFs can be found, for example in the Walter et. al.  paper. May 23 '16 at 16:37
• @RichieSams: Walter et. al.  is basically still the state-of-the art for dielectric rough surfaces, but to make it work well you need a good sampling which was published just recently by Heitz and D'Eon the 2014 paper "Importance Sampling Microfacet-Based BSDFs using the Distribution of Visible Normals". And note that it is a single-scattering model which neglects inter-reflections between microfacets making it visibly dark for higher roughness values. See my question "Compensation for energy loss in single-scattering microfacet BSDF models" for more details. May 23 '16 at 16:53
• Just wanted to point out that if you choose probability = fresnel() as the question suggested, then when you divide by the probability, you cancel out the Fresnel factor that would normally be multiplied in. So (in the discrete, two-Dirac case) you end up with the ray contribution not including any Fresnel factor at all. It's standard importance-sampling theory, but I thought I'd point that out as a potentially confusing issue. May 23 '16 at 18:22
• @Nathan, I incorporated your notice into the answer. May 24 '16 at 11:27