Sunday, October 21, 2007

Probabilistic reflection/refraction

In the response to the previous post, Thomas said he would choose probabilistically. If you are sending many rays per pixel I definitely agree this is the way to go. I believe that approach was first suggested in Kajiya's 86 path tracing paper.

color trace(ray r, depth d)
color c
if (r hits scene at point p)
c = direct_light(p)
if (depth < maxdepth)
if (random < ks)
c+= trace(reflected_ray)
else
c+= trace(refracted_ray)
else
c = background(r)
return c

Note that the weighting is implicit; if you trace reflected_ray a fraction ks of the time, that is just like tracing it every time and weighting it by ks. And as Thomas said, the best images come when you use Fresnel equations.

2 comments:

Jared Hoberock said...

I recently implemented this in my renderer, and happened to have this comparison image.

http://img.waffleimages.com/e98c771bcbb71ba3339d97aa2892de3e6cba4d07/importance_sampling_glass_comparison.jpg

The glass on the left was sampled by choosing uniformly at random between transmission and reflection.

The glass on the right was sampled by evaluating the Fresnel terms for reflection & refraction and importance sampling between them.

Overall, the importance sampling method generates a much smoother glass ball, except for the reflection of the light. If we took into account the position of the light at scattering time, we could account for this, but this is often not convenient.

I wonder if there's a way to do even better using only local scattering knowledge?

Unknown said...

the difference in variance is quite remarkable :)

about the reflection of the light source, i think if you used sufficiently many samples for noise on the diffuse walls and glossy floor to disappear, the reflection would also be smooth. in other words, perhaps it was over-sampled before?