Blog Archives

Optimizations: Lighting and Thresholds

National Geographic

We will be discussing different ways to optimize scenes for rendering.

For this one I will visit an old attribute of the Physical Light shader. You can connect the Physical Light Shader in the area light (or many light types) under the mental ray rollout and under the Custom Shaders rollout (here just attached to Light Shader, I am not emitting photons)

Here is the default setup for the Physical Light Shader:

This attribute is called the Threshold. According to the docs it is described:

[threshold] is for optimization: if the illumination is less than threshold, the illumination can be discarded and no shadow rays need to be cast. The default is 0.

This means that anything receiving less than the described threshold of light will neither cast shadow rays or add the light from it.

You might think this is handled by the regular falloff of the light where objects outside its influence will not attempt to run the light shader. This isn’t true. Your renderer is blind to this information and will try the calculation anyway only to return no illumination. (The renderer never knows unless it tries.) So this parameter is a hint that it shouldn’t even try beyond a certain level of ‘darkness’.

How will this help?

In VFX work you may have expansive scenes as opposed to cozy interiors. In many cases the lights are only going to affect objects nearby (this is true of other scenes than just VFX but means most in these scenarios). If I have 20 practical lights in my scene then my light loop will try to run the list and figure out their contribution. In a case where the lights are expensive (like an area light) this can mean large amounts of rays are traced for lights that are too far away to make a visual difference.

In the below example I have magnified the result so you can see how it helps cut back on expense.

A close up of this simple scene and a large area light with the physical light attached has a sample limit of 128. This image renders with the following statistics:

RC 0.3 info : rendering statistics
RC 0.3 info : type                   number       per eye ray
RC 0.3 info : eye rays               946945              1.00
RC 0.3 info : shadow rays         105251572            111.15
RC 0.3 info : probe rays            3479348              3.67
RC 0.3 info : fg points interpolated 946945              1.00
RC 0.3  info : wallclock  0:01:12.35 for rendering

You can see here that I am casting 111.15 shadow rays (samples for the area light) on average for each eye ray.

So let’s zoom way out where the light won’t be able to illuminate the scene.

Now look at the statistics:

RC 0.4 info : rendering statistics
RC 0.4 info : type                   number       per eye ray
RC 0.4 info : eye rays               474331              1.00
RC 0.4 info : shadow rays          54898447            115.74
RC 0.4 info : probe rays             298992              0.63
RC 0.4 info : fg points interpolated 474331              1.00
RC 0.3  info : wallclock  0:00:29.78 for rendering

Ouch, still a lot of rays per eye ray even though there’s nothing out there. Just a long expanse of flat dark plane.

The renderer knows the area light is out there somewhere. . .and it’s trying to sample it.

So now let’s look at the parameter. Generally speaking a good binary search is good for testing settings. Get the frame where you want it and jump halfway to say 0.5 The next test can be 0.25

If you need to go up, go to 0.375; if down go to .125, etc. Each time taking a halfway point to get it where you want visually.

So let’s say I am eventually going to zoom into the closeup with the cubes. So that is my measure of what I want it to look like at its best. (Assuming I don’t animate the parameter.) So from the original setting of 0.000 let’s try 0.5 first and see what makes the most sense.

0.5 Threshold

0.25 Threshold

0.125 Threshold


It looks like a threshold of .125 looks pretty identical to the first image. The stats for threshold 0.125 are:

RC 0.3 info : rendering statistics
RC 0.3 info : type                   number       per eye ray  original
RC 0.3 info : eye rays               946837              1.00      1.00
RC 0.3 info : shadow rays         105195167            111.10    111.15
RC 0.3 info : probe rays            3478268              3.67      3.67
RC 0.3 info : fg points interpolated 946837              1.00      1.00
RC 0.3  info : wallclock  0:01:06.41 for rendering

Ok, there’s not a huge difference there, but I didn’t expect one because the images are the same. So now let’s zoom out again.

RC 0.3 info : rendering statistics
RC 0.3 info : type                   number       per eye ray  original (zoomed out)
RC 0.3 info : eye rays               514853              1.00      1.00
RC 0.3 info : shadow rays          11272699             21.89    115.74
RC 0.3 info : probe rays             312064              0.61      0.63
RC 0.3 info : fg points interpolated 514853              1.00      1.00
RC 0.3  info : wallclock  0:00:13.38 for rendering

We’ve gone from over 100 shadows rays to just 22 per eye ray. And the render time was cut in half!

Even though this is a trivial scene, you can see that multiple lights spread out across the scene will introduce overhead for areas they don’t even illuminate. For example, this image below if rendered would be very expensive. But lights down the bridge don’t contribute to the foreground and vice versa.

So spending a few minutes using this setting along with Brute Force-like Sampling and Progressive Rendering can help you quickly find a setting you can live with and render much faster than before.