, , , ,

Now that we have the theory side of things down cold, it’s time to dish out the recipe! I’ll help you through it with a practical example.

This method works best before you’ve dived into the Compositor and started adding nodes. You’ll need about five test renders (three if you’re lucky), and after a few trial runs you should be able to run through the critical parts in about five minutes (including test renders). It’s split into three phases, one of which you’ll probably never see.

Phase 1: Baseline

  • Render a test scene with a low sample count as an image reference; ten samples per pixel is a good starting point, I figure, but feel free to adjust to taste.
  • In the Compositor, add a Gaussian blur of about 10 pixels.
  • In a new render slot, set Clamp Direct to 0.0001 or less and render an indirect reference.
  • In the image viewer, find the brightest RGB value that isn’t a light within the blurred indirect reference, the brightest you simply can’t chop down.
  • Set Clamp Indirect to the average of the RGB channels in the above value, Clamp Direct back to 0.0, and render a candidate result to a new render slot.
  • Compare the image reference to the unblurred candidate. Do you like the results?

YES: You’re done! Add or adjust your post-processing effects in the Compositor, crank the sample count to match your time budget, and render.
NO, there’s too many fireflies: Damn, you probably have a scene that clamping won”t help. Either raid Phase 3 for possible solutions, or use another technique.
NO, the fireflies are gone but parts of my scene darkened: Head to Phase 2, Refinement.

I’ve chosen a scene most of you should be familiar with.

Version 2 of that BMW scene, with the sample count dropped to 3 so it render in under 15 seconds.I’ve cut the sample count down to 3 (9 when you include AA), so the entire scene now renders in 11.75 seconds on my computer. Before I rendered it to slot 1, I mucked around with the nodes in the compositor view so I had a blurred version for reference.

The setup I'm using in the Compositor. Nothing fancy.I kept all the old Compositor nodes around, for reasons you’ll see later. Anyway, I next set the Clamp Direct value to 0.0001 (to remove all direct light), switched to render slot 2, and re-rendered. [HJH 2015/03/19: See addendum at the end of this post for a variation which saves a few test renders]

The indirect light off the BMW scene. It ain't pretty.Crapcrapcrapcrap, this is almost as bad as it can get. Most fireflies are caused by indirect light, yet a key part of this scene is the indirect light bouncing around inside that headlamp glass. Worse still, by bouncing between the Composite and RenderLayer view I can see that the fireflies I really want to get rid of are in those dark smudges on the floor. Ugh, I can already tell I’m going to have to compromise between the headlamp glass and fireflies.

For now, though, let’s go along with the recipe. The brightest pixels in the blurred Composite image are directly in the left headlamp, with RGB intensity (3.9, 4.3, 4.8), but as per the recipe I’ll ignore that (as well as the “CM” RGB values listed to their right, which come from further down the post-processing chain). The next brightest pixels are on the opposite side of the glass shell containing said headlight, which max out around (0.56, 0.63, 0.7). The average of that will be my Clamp Indirect value. While there, I’ll reset Clamp Direct to zero.

Setting the Clamp Indirect value, via MATH!Thank you, Blender, for permitting me to be lazy. Anyhoo, I’ll switch to slot 3 and rerender. Survey says…

The BMW scene, with indirect clamp at 0.63… dammit, I called it: those headlights look like crap. By bouncing between slots 1 and 3, I can see other areas that darkened up, like the second car’s side mirror and that thin strip at the base of the windshield, all of which are tolerable. Worst of all, though, the fireflies are completely gone. If it weren’t for those damn headlamps…. ugh fine, let’s move to Phase 2.

Phase 2: Refinement

  • Set Clamp Direct back to 0.00001, leave Clamp Indirect untouched, and replace the indirect reference with a new render.
  • Measure the bright area again and calculate a new per-channel average.
  • Swap Clamp Indirect with (Clamp Indirect * Clamp Indirect / new average)
  • Reset Clamp Direct to 0 and replace the old candidate with a new one. Like it?

YES: You’re done!
NO, the fireflies are back: Dammit, you have a scene that’s tough to clamp. Somewhere between this clamp value and the previous one, though, lies a compromise between fireflies and scene detail. Either settle for that, switch to another technique, do both, or raid Phase 3.
NO, something in the scene is still dark: Repeat Phase 2.

Right, chop out the direct light again, switch back to slot 2, and re-render…

The indirect portion of the scene, after clamping. Note the darkening?Whoa, the headlight sure darkened! In hindsight, this makes sense; each pixel is the average of the samples it contains, so by clipping every sample above the average we wound up shoving down the average and darkened the pixel.

Those pixels we sampled before are now at (0.1, 0.12, 0.14), so we’ll update the Clamp Indirect value as per the recipe and put Clamp Direct back to 0.0.

Updating the Clamp Indirect value a second time. Hooray for math!Ah, all those university math courses paid off. We’ll switch to slot 3, and re-render a new candidate. The second candidate. It's almost identical to the original reference... unfortunately.Huh, that’s almost identical to the original, unclamped version. You have to look reeeeeally closely to see any difference at all (the overlays are a necessity here). That, unfortunately, also means the fireflies are nearly identical too.

The recipe gives us a few options here. The easiest one is to bite the bullet and do a compromise between the two clamping values. If you wandered off the recipe a bit and saved your renders as you went along, you can pop them into the Compositor and fade between them, seeing exactly what your compromise will look like. I’m going to continue pretending I don’t have the time for such foolishness, and take the easiest easy route: average the two clamping values together.

The lazy person's solution: split the difference.That’s it for clamping, so let’s crank the sample count and let things ride. Unfortunately, “mpan3” picked some excellent defaults that dodge a lot of firefly issues, so I’ll render the scene at half the typical sample count. I’ll also put back the default node setup, and render a few comparisons to judge the results.

Comparing the low-ish sample clamped version to a similar lowish-sample without clamping and the original without clamping.Honestly? That blind compromise looks really good to me. Sure, the headlamp glare has darkened a bit, but we can correct for that by tweaking the Compositing nodes. The headlamp glass still lacks punch, but the increased sample count has decimated the fireflies! I did another render of a three-quarter split towards the upper value, and it actually looks a bit worse, as it doesn’t restore much of the headlamp reflections yet the fireflies start to creep back.

This really is about as good at it gets with clamping, and I bet that in your own scenes you’ll be satisfied after this phase. But let’s move on to Phase 3 anyway.

Phase 3: Perfectionism

  • First off, if you’ve reached this stage you’re either creating an animation and desperate to keep your sample count down, or spending too much time tweaking the clamp values. Take a moment to reconsider.
  • Still here? Let’s continue, then.
  • If the problem area is small, you could try multiple rendering passes. Tighten down the clamping and samples, then do a full render. Now relax or remove the clamping, bump up the sample count, and render just the problem areas to RGBA. If using Blender’s Compositor, overlay the windowed part; either way, re-render with the new settings. If not using compositor, merge the two via your magic of choice.
  • You can also tighten down Clamp Direct, using the exact same technique as above, or by doing both clamp values simultaneously. Since you’re probably clamping samples to remove fireflies, and they’re almost entirely due to indirect light, these methods are probably a waste of time.

If you clamp both Direct and Indirect at the same time, you eliminate the need to create an “indirect reference” render. Rather than do five renders, as I did above, you’d just do three. That can be a decent time savings, if even your test renders chew up time, but otherwise it offers little advantage over the above recipe and one disadvantage: if you looked carefully, you may have noticed that using clamping slowed down the render. It adds up to three branch operations, two divisions, 14 multiplies, and five adds for every light path it tracks back, with in this scene numbers about 51 million. Those ops add up, and when you clamp both values you pay a greater price.

Multiple rendering passes may be more your style, especially if you’re doing a still scene. I went back and re-rendered just the windshield and two headlights with different settings, saved all of the pre-compositing results to an HDR format, then abused the Compositor to overlay them all over the actual render. Frankenstein’s monster was then fed into the rest of the compositing nodes, in place of said render.

What happens when you layer multiple passes with different settings.Even though I spent no time trying to fuzz away the seams, the result looks better than the 20 sample version yet required about as much rendering time. I’ll admit this is a little impractical for most situations, but it never hurts to have another technique under your belt.

When I called this a “recipe,” I really meant it: while it should give you great results without any tweaking, there are still things to tweak. So go on, bake your own version!

2015/03/19: Addendum

Well, I’m feeling a bit silly. I was investigating a way to use a similar technique to tuning the Branched Path Tracer, saw this panel, and blinked twice:

The "passes" part of the Scene panel, set at defaultsAck, how could I have been so blind?! I clicked off the “Indirect” buttons for all of Diffuse, Glossy, and Transmission (this scene has no Subsurface shaders), and switched back to the node editor.

The Compositor, after enabling those extra data channels.There, I just saved a bunch of test renders! Here’s a thumbnail of the revised process:

Phase 1: Baseline

  • Create the above node layout in the Compositor, adding or removing Mix nodes depending on the shaders in your scene.
  • Render a test scene with a low sample count as an image reference.
  • In the image viewer, find the brightest RGB value in the Composite variant of the result that isn’t a light within the blurred indirect reference, the brightest pixel you simply can’t chop down.
  • Set Clamp Indirect to the average of the RGB channels in the above value, and render a candidate result to a new render slot.
  • Compare the RenderLayer image reference to the RenderLayer candidate. Branch as per before.

Phase 2: Refinement

  • Measure the bright area again in the Composite variant, and calculate a new per-channel average.
  • Swap Clamp Indirect with (Clamp Indirect * Clamp Indirect / new average)
  • Render again. Compare RenderLayer to RenderLayer, and branch as before.

This should shave off a few minutes, without compromising quality.