# About the use of Russian Roulette in Smallpt

I was taking a look at Smallpt (http://www.kevinbeason.com/smallpt), more specifically at the Russian Roulette part. Actually, RR is used in two places along the code: first, to determine ray termination; and second, for the rendering of dielectrics.

That is the code for the ray termination case (expanded code version):

// p = maximum reflectance
// fr = BRDF
double p = fr.x > fr.y && fr.x > fr.z ? fr.x : fr.y > fr.z ? fr.y : fr.z;

if ( ++depth > 5 )
if ( erand48(Xi) < p )
fr = fr * ( 1 / p );
else
return obj.emission;


After five bounces, RR is used to determine if the ray path continues or not. If it continues, the BRDF is scaled to compensate for it. This is Ok for me.

RR is also used in a second code segment to select between refraction or transmission during the rendering of dielectrics (expanded code version):

double Re = R0 + ( 1 - R0 ) * cost * cost * cost * cost * cost;
double Tr = 1 - Re;
double P = .25 + .5 * Re;
double RP = Re / P;
double TP = Tr / ( 1 - P );
Vec Lo; // output radiance

if ( depth > 2 )
if ( erand48(Xi) < P )
Lo = radiance(reflRay,depth,Xi) * RP;
else
Lo = radiance(Ray(x,tdir),depth,Xi) * TP;
else
Lo = radiance(reflRay,depth,Xi) * Re + radiance(Ray(x,tdir),depth,Xi) * Tr;


According to the code above, the path branches recursively if the ray has bounced up to two times. After two bounces, however, RR is used to select the path to be followed. This is also Ok for me.

What is a bit confusing is the fact that the radiance returned by both possible non-branching paths (refraction and transmission) is scaled. I understand that there are different probabilities regarding reflection and transmission. However, if for instance Re = 0.3 and Tr = 0.7, and 100 rays strike the surface, about 30% of the rays will be reflected and 70% of will be transmitted due RR. In this case, I understand that there is no path termination neither energy loss, so there wouldn't be anything to compensate for.

Thus, my first two questions are: why are these radiances scaled? Should they be scaled, or would it work without scaling at all?

My third question is related to the scaling factors: Why the author has used P, RP and TP instead of Re and Tr?

Any indication of a good reading about this topic is also very welcome!!

Thank you!

## 1 Answer

The reflected and transmitted values need to be scaled because they are not sampled proportionally to their contribution. You'll notice how the decision whether to reflect or transmit is made based on P, not Re.

About why that scaling has been done in the first place, only the author can give you the definitive answer. My guess is that this is done to prevent extreme values that would come from tiny probabilities. Imagine that Re is 0.001 and is used without scaling. Then only one in 1000 rays would reflect, and the contribution of that ray would be multiplied by 1000. At a render with, say, 64 rays per pixel, this would leave very visible artefacts, as not every pixel would get a reflected ray. The scaling from this code snipped on the other hand makes sure that the ray budget is more evenly distributed between reflection and transmission and that each potential path taken is guaranteed at least 25% or the rays.

For further reading about path tracing, there is no better and comprehensive resource than www.pbrt.org - both the book and the source code are worth reading.

• You went exactly to the point! I did not realize that the decision was being made on top of a different probability (i.e. 0.25 + 0.5 * Re). Now the scaling makes total sense. Actually, this framework seems to be quite flexible since the decision of which path to follow can be made from a probability that can be completely detached from the original one (e.g. P could be a fixed value) since RP and TP are recomputed to account for it. Obviously, some choices for P may have better justifications and may work better than others (as the one you have discussed above). Thank you Stefan! – Christian Pagot Jul 27 '17 at 23:16