-
Concept: Russian Roulette
-
The Problem
- Path tracing is recursive — paths can bounce infinitely
- Truncating at fixed depth introduces bias (misses long light paths)
- Need an unbiased way to terminate paths
-
How Russian Roulette Works
- At each bounce, randomly decide to continue or terminate
- Survival probability:
q (typically based on path throughput)
- If
random() < q: continue, divide contribution by q
- If
random() >= q: terminate, return 0
- This is unbiased because:
E[contribution] = q * (true_contribution / q) + (1-q) * 0 = true_contribution
-
Choosing the Survival Probability
- Common choice:
q = max(throughput.r, throughput.g, throughput.b)
- Throughput = product of BRDF weights along the path
- As path gets darker, more likely to terminate
- Prevents wasting computation on paths that contribute little
- Clamp:
q = clamp(q, 0.05, 0.95)
- Minimum 5%: prevents infinite loops (q=0 would never terminate)
- Maximum 95%: prevents very bright paths from being over-weighted
- Alternative:
q = luminance(throughput) — single value, perceptually weighted
-
Effect on Variance
- Russian roulette does NOT reduce variance — it can increase it
- Paths that survive get boosted by
1/q → higher individual contribution
- But: eliminates wasted computation on low-contribution paths
- Net effect: same expected value, potentially higher variance, but faster convergence per unit time
-
Splitting (Opposite of Russian Roulette)
- When throughput is HIGH: spawn multiple child rays
- Reduces variance for bright paths at the cost of more computation
- Rarely used in real-time (too expensive)
- Used in offline rendering for caustics and other difficult paths