chunky-dev / chunky-dev/chunky
Russian Roulette Ray Death Hurts Performance Instead Of Helping
- Dominant language
- Java
- Stars
- 738
- Forks
- 78
- Avg merge
- 10h 5m
- Merged PRs (30d)
- 3
Description
Russian Roulette as implemented right now kills rays half of the time for each bounce after hitting the Ray Depth, which it increases variance(noise) and time, instead of reducing time with minimal increase to variance.
According to The PBR Book, Russian Roulette should kill rays (prior to reaching RD, I believe) that are less likely to make an impact, then scale the result of the ones that survive. Right now, there is no scaling done, so the output is not just less efficient it is also technically wrong.
Right now, this quoted example of what not to do, is exactly what we are doing, but technically wrong (We use 50% instead of 99%, and dont weight surviving rays by 2, thus decreasing the average light per ray, instead of keeping it constant):
> One pitfall is that poorly chosen Russian roulette weights can substantially increase variance. Imagine applying Russian roulette to all of the camera rays with a termination probability of .99: we’d only trace 1% of the camera rays, weighting each of them by 1/.01 = 100. The resulting image would still be “correct” in a strictly mathematical sense, although visually the result would be terrible: mostly black pixels with a few very bright ones.
([PBR Book, section 13.7](https://www.pbr-book.org/3ed-2018/Monte_Carlo_Integration/Russian_Roulette_and_Splitting))
------
**Suggested quick fix:** Disable RR as it stands. This should decrease variance and time spent, overall increasing render efficiency, while losing some minute effects of higher RD (which can be achieved with higher RD, as is the point of that option).
**Suggested fix (probably for 2.5.0):** Determine an effective RR algorithm and implement it. Splitting may help.
The goal of Russian Roulette is to reduct render time by reducing rays traced, if they won't contribute much:
> Russian roulette makes it possible to also skip tracing rays when the integrand’s value is very low but not necessarily 0, while still computing the correct value on average. [...] With probability 1-q, the integrand is still evaluated but is weighted by a term, 1/(1-q), that effectively accounts for all of the samples that were skipped.
([PBR Book, section 13.7](https://www.pbr-book.org/3ed-2018/Monte_Carlo_Integration/Russian_Roulette_and_Splitting))
Contributor guide
Research direction
Start by locating the Russian Roulette implementation in the Java path-tracing code and inspect how ray depth, termination probability, and surviving-ray weights are handled. Compare the behavior with section 13.7 of the PBR Book. Done means the renderer avoids the current biased or inefficient behavior, with rendering results and performance checked against the existing approach.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- computer-graphics, performance
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100