Cycles noise - why can't it do adaptive subsampling? (Is there a workaround?)

Is there something intrinsic in the way Cycles renders that prevents it doing adaptive subsampling?

It seems that if you want to reduce noise in your render, even if the noise is only visible in some parts of the image, the only thing you can do is increase the number of samples across the whole render.

But it’s easy to identify which parts of the image need more samples, just by looking at the contrast of neighbouring pixels.

The noise in this render is easy to spot, and easy to identify algorithmically:

http://i.imgur.com/JkPrIDm.png

I don’t want to increase the samples across the whole image - just the pixels that have a high contrast compared to their immediate neighbours.

In Mental Ray, you specify a minimum and maximum number of sub samples, and a contrast ratio. MR compares each pixel to its neighbours and only subsamples it if the contrast is greater than a certain amount.

Why can’t Cycles do this?

Workaround possibility: Is there a way to control the number of samples Cycles calculates for each pixel by using a map? So you could do a low-sample render, run it through a high-pass filter to find the noisy areas, then use that map to control Cycles’ subsampling?

At the moment, Cycles seems to waste so much time subsampling areas that don’t need it that I end up ditching Cycles and going back to Blender Internal, just so I can get my animations rendered on time…

I tend to agree… there could be some workarounds. Arnold also has this issue with noise - only increasing samples of certain ray types, or of the whole in general; and sometimes using a Pixel Filter with wider Pixel Width gets rid of this noise, like 2 or 4 pixels using Gaussian, but that sometimes blurs fine detail.

Example, split your ray types, and if there is a lot of noise in your glossy surface, increase those samples without affecting the others. … very much to the eye - also take a look at your AOV’s to see what is causing noise and what isn’t, then you can up those ray types - which Cycles can also do, though I do not know of a clamp, like Arnold.

The following tips for noise in Arnold are very helpful, and I can’t help but notice the way Cycles uses rays also works in a similar way. This will help understand how the noise works, and how to fix it.
https://support.solidangle.com/display/softtut/Removing+Noise

Concerning noise, I do prefer methods used in Mental Ray or even the Biased render engine Redshift3D - which I recommend as a model for the future, as you mentioned.

But for Blender, there is a nifty tutorial on Blender Cookie where I saw a Bilateral Blur compositing system that will get rid of this noise dynamically once you figure out how to set it up - very much like your Min-Max blurring system - post render. I have not tried it, but I think I may to save on my renders in production.

Yeah, you can use the branched path mode to set samples by ray type, same as Arnold. Cycles has the clamp options too, they’re in the sampling tab. There’s even a built-in option to set clamping to different levels for direct and indirect light, which Arnold doesn’t (yet) have, you have to do it by hand in post by clamping individual AOVs.

Btw, contrast sampling like the old adaptive sampling feature in MR generally only helps with edges, it won’t help with noise usually. To get noise AND edges you need a more advanced noise-detection function than just contrast, like what MR’s unified sampling does, or Vray DMC sampling. There actually IS a patch in development for this in Cycles (it comes bundled with a metropolis sampler as well). It’s not finished yet though: https://developer.blender.org/T38401

Thanks for your thoughts!

I’ve had a go at setting it up - it’s not trivial to do, and it takes a fair bit of tweaking to get it working for any particular scene. It certainly has its uses, but it’s a bit hacky, and it introduces its own artifacts, catching and blurring some details that it shouldn’t.

Forgive me, the_Ninja - not sure I get you. MR’s simple contrast approach (if any two neighbouring pixels’ RGBA channels differ by more than x then resample both of them, up to a set maximum) works surprisingly well to the eye. Haven’t noticed it favouring edge pixels over any other pixels. After all, it’s contrast that determines whether noise is actually visible, so using pure contrast values to determine sub-sampling depth just seems right.

What I find so frustrating about Cycles is that the noise / sparklies are so simple to find algorithmically, and the most basic approach “hey, lots of contrast between those two pixels, let’s up the AA samples just for them” would have a huge effect while still being economical, render-wise.

Thoughts:

  • Maybe Cycles just can’t do calculations based on more than the one pixel being rendered. Could be that to keep the rendering algorithms GPU-friendly [ie multi-threadable] each pixel has to be looked at in absolute isolation
  • If noise [contrasting pixels] is found at the edge of a bucket, Cycles would have to revisit the pixels at the edge of an already completed bucket. That may not be trivial to do, and may kill off GPU compatibility.

I wonder if it’s worth asking on the scripting forum how tricky it is to write your own “renderer” - a script that calls on Cycles to render just one pixel at a time, so you can handle this contrast detection yourself. Could well end up slower than just brute-force oversampling everything though… (and it’d throw GPU rendering out the window. 1 x 1 pixel buckets… eek)

Map-based sub-sampling might be doable, though; a two pass approach: the first render to find the areas likely to be noisy, the final render sub-sampling based on the areas found in the first.

Well, it was worth asking, I suppose :slight_smile:

Yes :slight_smile:

“hey, lots of contrast between those two pixels, let’s up the AA samples just for them”

There is the Clamp setting for, I think, disable Caustics can help too.
The next Blender 2.71 include Direct/Indirect clamping for more control.
The patch J_the_Ninja mention also include Adaptive stopping, like Luxrender.

Brecht is working on “Improved importance sampling for Beckmann and GGX”

You get the “Daily Builds” at http://builder.blender.org/download/
to play with implemented new features before release.
I think some patches are going to trunk shortly after 2.71 release.

Have fun, mib

I’ve wondered about this very same concept and I think it would be a real game changer if achieved, but I couldn’t know less about the programming logistics of such a feature. I hope we’ll see it in Cycles soon, but the Cycles developers have already proven themselves capable considering how new the engine is, so I think if this is a practical it will come around sooner or later.

Pointless comment.

I used to, sometimes still am, having big problems with noise. Although I’ve learned some tricks, I’d still like some manual control. What is helping me so far (I’m kinda new, so correct anything stupid I say):

  • Instead of adding multiple ceiling area lights, I seem to get much reduced noise if I have only one emitter object (i.e. faces in a ceiling tile grid).
  • If I need to simulate a camera flash, using a regular point light seems way better than a very tiny area light.
  • For window light, I just use an atmosphere plane for the blue tones, and a normal sun object (with sun position addon) for the yellow tones (and relatively sharp shadows). I don’t use HDRI’s much anymore.
  • MIS in the above circumstances (more lights, and very varied sizes for mesh based only emitters) can to me often be more of a curse than a help (default resolution, as higher seems to crash my Blender a lot).
  • I have clamping set at 2 for both, using 2-3 indirect bounces (if any), and combined with just a tad of camera depth of field, much of the noise and fireflies I get will be manageable at 500 samples. However, I’m still trying to learn, so my “scenes” are pretty basic so far.

Again, feel free to correct me if I have made some really stupid observations - no point in passing on those to others :slight_smile:

Edit: Oh, I also do some photography, where I use addon filters to handle noise. I’ve never thought of it before, but are these too specific to photography or could they actually help noisy renders?

if you are dealing with many lights… used branched path tracing with sample all lights (direct and indirect) options… may only be in the new blender.