Archive for January, 2011
Now You’re Lighting With Portals
I hate dome lights. You always waste a ton of rays that are occluded by geometry, and the situation gets even worse when lighting indoor scenes with exterior dome lights!
So why not help your renderer out and place portals that, when hit, teleport to the dome light. Then instead of sampling the whole skydome, we just sample the portals, and avoid sending rays where we know they will be occluded.
As an example, here’s the Sponza scene using an exterior (uniform) dome light, rendered using unidirectional path tracing with multiple importance sampling:
Lots of rays never manage to find the open roof, so we get plenty of noise. Now let’s replace the dome light with a portal that covers the open roof, then allow that to be sampled instead:
Noise is greatly reduced, for exactly the same number of rays.
The sampling algorithm is simple enough to implement in your GPU path tracer of choice: sample the portal and use the usual conversion between pdf wrt area (the portal) and pdf wrt solid angle (the dome):
\[P_\sigma = \frac{P_A \|\mathbf{v}\|^2}{\cos(\theta)} = \frac{P_A \|\mathbf{v}\|^3}{\mathbf{v}.\mathbf{n}}\]
Where v is the vector between target point and the portal point, and n is the portal normal.
Two-Way Path Tracing
This post is about a path tracing technique that sits between unidirectional path tracing and bidirectional path tracing.
For want of a better name, let’s call this two-way path tracing. It’s defined as follows:
- Trace eye rays, handle light source intersections and sample light sources explicitly
- Trace light rays, handle sensor intersections and sample sensors explicitly
- When computing weights for multiple importance sampling, take both tracing methods into account
So you can think of this technique as either:
- Unidirectional path tracing in both directions at once
- Bidirectional path tracing, but we only connect sub-paths if one of the sub-paths has one vertex
So why is this interesting? Because:
- Like unidirectional path tracing, you only need to track a fixed amount of state, regardless of maximum path length. This is potentially nice for GPU implementations where you usually want to avoid hitting memory and have a large number of paths in flight.
- You can efficiently multiple importance sample between forward and reverse paths, so you can get reduced variance compared to unidirectional path tracing for some types of scenes (e.g. caustics).
In this post I’d like to cover how to multiple importance sample between forward and reverse paths, and show some test images.

