Better adaptive sampling in dark areas

Component:YafaRay Core
Category:feature request
Assigned:David Bluecame


Montecarlo algorithms used in final gather and path tracing produce a lot of variation in difficult-to-reach dark areas and "clustering" of radiance results instead of spreading it out in a regular pattern. Clustering is a known issue of true stochastic algorithms and it is an issue latter magnified by adaptive sampling based on a color thresold, which could be useful for brighter areas and gradients but does a poor job sampling very dark clusters that integrate little or no indirect lighting in the first passes.

In the image below, you can see this effect on the bottom of the red wall, with dark patches that get consistently ignored by adaptive sampling even with a thresold as low as 0.0008. A differential thresold based on image darkness could be a solution though I am not sure whether a color thresold system is really robust enough to take on a problem like this, since a thresold on dark areas should probably stay infinitesimal or be 0 while other areas in a normal render could use a thresold as high as 0.02. I mean the difference seems to describe a geometrical progression problem as many other stuff in montecarlo engines and this problem could be also happening in less dark areas without us noticing. Maybe there are better solutions based on samples divergence for instace or there is some paper that specifically takes on this issue. The new feature "Dark areas noise detection" does not make much of a difference at the moment regarding this issue.

You can download the file at

cornellbox271e.png155.12 KB



Assigned to:Anonymous» David Bluecame
Status:active» needs review


YafaRay-E v2.0.1 already has a factor to automatic AA Threshold adjust for dark pixels.

If you use a factor, for example, 0.8 it will do an automatic calculation of the AA threshold based on the pixel brightness. In that case you probably have to increase the normal threshold as it will be very much lower in the dark pixels.

However, I've seen that the current limit I set for this dark areas factor (currently max. 0.8) is probably not enough for your scene. So, in the next YafaRay-E version I will increase that factor to 1.0, so you can get a much stronger effect. If you chose the factor to be 1.0, then the normal threshold should be higher (maybe even around 0.5), but that's up to you to experiment.

The changes are (first I thought about changing the limit from 0.8 to 0.999 but later decided to change it to 1.0:


If you don't want to wait, please modify directly those values in you existing Exporter and try again, for example dark factor=1.0 and normal threshold around 0.5, for a start...

Please let me know if that is good enough or if I have to make further changes to the code to get what you need.


Status:needs review» fixed

This should be better in YafaRay-E v2.0.2. As a starting test, try threshold 0.5 and dark detection factor 1.000


Hi David

Thanks for these changes and for the pronto feedback. It is a very good idea that we set differential thresolds for pixel brightness. However, I do not understand yet how this "Dark areas noise detector factor" is really working on the image, whether it multiplies for "Thresold" value or it is the setting that actually detects a dark area. As it is now, it is not very intuitive to use. Could you explain it a bit more how it works ?

As an user, an idea I have got is defining image brightness using the zone system. For mid tones (zone V) for instance YafaRay users use between a 0.01 and 0.004 thresold for a quality result. It would be great if we could identify the best thresold for each zone. The result will probably describe an "S" curve.




The actual formula for the AA threshold for each pixel depends on the AA threshold parameter, the dark factor setting and the pixel value as follows:

AA_threshold_scaled = AA_theshold_parameter * ( 1.0 + ( (pixColBrigthness - 1.0) * AA_dark_threshold_factor) );


If the dark factor is 0.0, then the AA threshold is the same for all pixels regardless their brightness. This is the default behavior and the behavior of all versions until v2.0.0


If you set dark factor to 1.0, then the AA threshold for each pixel is multiplied by the pixel brightness, so a pixel with brightness 1.0 will use the original AA threshold, a pixel with brightness 0.5 will use half ot the AA threshold and so on. A black pixel with brightness 0.0 will have an AA threshold of 0.0 as well.


If you set intermediate dark factor values between 0.0 and 1.0, then it will do something in between, acording to the formula.


So, it's not really a "different" threshold for the dark areas, but a progressive AA threshold that depends on per-pixel  brightness. This is also why you need to increase the AA threshold parameter if most of the scene is very dark and you set a high dark factor, like 1.0, because the actual AA threshold used for all those dark pixels will be very low (multiplied brightness by AA parameter)


EDIT:  As of the current implementation (as the code is currently using that formula I put above without any limits on its result), if you use for example a dark factor 1.0 and you have very bright pixels with, for example, brightness 2.0, then the AA threshold used for those bright pixels will be 2 x AA_threshold parameter.


I hope this clarifies how this works.


thanks David for the explanation, I will do some tests and share my results.


I have tried the scene above, looking for optimal thresold for pixel brightness in 0.10 steps. My results are more or less

Pixel Brightness / Optimal thresold:

  • 0.05 / 0.0006
  • 0.10 / 0.0008
  • 0.20 / 0.001
  • 0.30 / 0.002
  • 0.40 / 0.004
  • 0.50 / 0.006
  • 0.60 / 0.008
  • 0.70 / 0.01
  • 0.80 / 0.02
  • 0.90 / 0.05

So far it does not like a linear progression but a curve. It is possible that the curve is assimilable to the gamma correction curves used in sRGB color spaces, so we do sampling of the 2D image plane like the human eye and the CDD sensors and color spaces modelled after it do, with more information sampling and encoding in the lower part of the histogram. It is also possible that it just describes the beginning of a Gauss bell. With this kind of relative low sampling requirements in the upper part of the histogram (0.04 thresold), the montecarlo noise will probably remain there but we just can not see it. Also with this kind of sampling balance we would put more sampling work where it is really needed. Anyway I have to try with more scenes.


Status:fixed» needs review



Please, will you specify what changes do you think would be necessary?

Thanks and best regards.


Status:needs review» fixed


As no further requests have been made about this, I will mark it as fixed for now.


I am still doing tests. I will post results as soon as I reach some clear conclusion about this, since the sampling requirements and the minimun thresold needed changes with montecarlo variance, for instance an area with pixel brightness = 0.10 but with low variance would require a different thresold than an area with the same average pixel brightness but with more variance. I also need to test thresolds on highlights to see whether we reach a "plateau" so the thresold requirements descrive a gauss curve or the thresold keeps on accelerating with more pixel brighness. We need to keep working on this since IMO it will make a big difference if we implement a good flexible thresold curve. Sorry about the delay.


Status:fixed» needs review


No problem, moving it back to "needs review".

Best regards.



I have tested with the scene below. Not only montecarlo variation leads to a lower threshold, sometimes different colors with the same brightness value (HSV) react differently to a given threshold. I also believe that with hightlights the threshold curve reachs a plateau, therefore the curve can be assimilated to a gauss bell. I would like to test a couple more of scenes. I think If we implement it well it could mean very significative render time savings.

Pixel brightness (HSV) = optimal thresold

0.10= 0.0001

0.20= .001

0.30= .002

0.40= .0035

0.50= .0055

0.60= .0075

0.70= .010

0.80= .015

0.90= .025

1.00= .04

1.20= .08

1.40= .095

1.80= .100

Optimal threshold curve


Please will you give me some kind of details/specifications about what's needed?


Status:needs review» ready to commit


In the upcoming YafaRay v3.0.0 there will be a new Dark Noise Detection Type parameter that will work as follows:

* "none" no special Dark detection, AA threshold will be constant (traditional way) as of the AA threshold parameter

* "linear", this is the Dark Detection variable AA threshold I introduced in previous versions, where the Dark Threshold Factor, combined with each pixel brightness, will give a per-pixel AA threshold for better dark areas noise detection.

* "curve" (new). In this mode, the per-pixel AA threshold will be calculated based on the table that samo has calculated. For your reference, this is the result of the new "curve" function for 200 examples of pixel brightness (0.00 black, 1.00 "full" bright, > 1.00 extra brightness (like in bright lights))

pixel brightness=0.00 AA threshold=0.0001
pixel brightness=0.01 AA threshold=0.0001
pixel brightness=0.02 AA threshold=0.0001
pixel brightness=0.03 AA threshold=0.0001
pixel brightness=0.04 AA threshold=0.0001
pixel brightness=0.05 AA threshold=0.0001
pixel brightness=0.06 AA threshold=0.0001
pixel brightness=0.07 AA threshold=0.0001
pixel brightness=0.08 AA threshold=0.0001
pixel brightness=0.09 AA threshold=0.0001
pixel brightness=0.10 AA threshold=0.0001
pixel brightness=0.11 AA threshold=0.0002
pixel brightness=0.12 AA threshold=0.0003
pixel brightness=0.13 AA threshold=0.0004
pixel brightness=0.14 AA threshold=0.0005
pixel brightness=0.15 AA threshold=0.0006
pixel brightness=0.16 AA threshold=0.0006
pixel brightness=0.17 AA threshold=0.0007
pixel brightness=0.18 AA threshold=0.0008
pixel brightness=0.19 AA threshold=0.0009
pixel brightness=0.20 AA threshold=0.0010
pixel brightness=0.21 AA threshold=0.0011
pixel brightness=0.22 AA threshold=0.0012
pixel brightness=0.23 AA threshold=0.0013
pixel brightness=0.24 AA threshold=0.0014
pixel brightness=0.25 AA threshold=0.0015
pixel brightness=0.26 AA threshold=0.0016
pixel brightness=0.27 AA threshold=0.0017
pixel brightness=0.28 AA threshold=0.0018
pixel brightness=0.29 AA threshold=0.0019
pixel brightness=0.30 AA threshold=0.0020
pixel brightness=0.31 AA threshold=0.0022
pixel brightness=0.32 AA threshold=0.0023
pixel brightness=0.33 AA threshold=0.0025
pixel brightness=0.34 AA threshold=0.0026
pixel brightness=0.35 AA threshold=0.0027
pixel brightness=0.36 AA threshold=0.0029
pixel brightness=0.37 AA threshold=0.0030
pixel brightness=0.38 AA threshold=0.0032
pixel brightness=0.39 AA threshold=0.0033
pixel brightness=0.40 AA threshold=0.0035
pixel brightness=0.41 AA threshold=0.0037
pixel brightness=0.42 AA threshold=0.0039
pixel brightness=0.43 AA threshold=0.0041
pixel brightness=0.44 AA threshold=0.0043
pixel brightness=0.45 AA threshold=0.0045
pixel brightness=0.46 AA threshold=0.0047
pixel brightness=0.47 AA threshold=0.0049
pixel brightness=0.48 AA threshold=0.0051
pixel brightness=0.49 AA threshold=0.0053
pixel brightness=0.50 AA threshold=0.0055
pixel brightness=0.51 AA threshold=0.0057
pixel brightness=0.52 AA threshold=0.0059
pixel brightness=0.53 AA threshold=0.0061
pixel brightness=0.54 AA threshold=0.0063
pixel brightness=0.55 AA threshold=0.0065
pixel brightness=0.56 AA threshold=0.0067
pixel brightness=0.57 AA threshold=0.0069
pixel brightness=0.58 AA threshold=0.0071
pixel brightness=0.59 AA threshold=0.0073
pixel brightness=0.60 AA threshold=0.0075
pixel brightness=0.61 AA threshold=0.0077
pixel brightness=0.62 AA threshold=0.0080
pixel brightness=0.63 AA threshold=0.0082
pixel brightness=0.64 AA threshold=0.0085
pixel brightness=0.65 AA threshold=0.0087
pixel brightness=0.66 AA threshold=0.0090
pixel brightness=0.67 AA threshold=0.0093
pixel brightness=0.68 AA threshold=0.0095
pixel brightness=0.69 AA threshold=0.0097
pixel brightness=0.70 AA threshold=0.0100
pixel brightness=0.71 AA threshold=0.0105
pixel brightness=0.72 AA threshold=0.0110
pixel brightness=0.73 AA threshold=0.0115
pixel brightness=0.74 AA threshold=0.0120
pixel brightness=0.75 AA threshold=0.0125
pixel brightness=0.76 AA threshold=0.0130
pixel brightness=0.77 AA threshold=0.0135
pixel brightness=0.78 AA threshold=0.0140
pixel brightness=0.79 AA threshold=0.0145
pixel brightness=0.80 AA threshold=0.0150
pixel brightness=0.81 AA threshold=0.0160
pixel brightness=0.82 AA threshold=0.0170
pixel brightness=0.83 AA threshold=0.0180
pixel brightness=0.84 AA threshold=0.0190
pixel brightness=0.85 AA threshold=0.0200
pixel brightness=0.86 AA threshold=0.0210
pixel brightness=0.87 AA threshold=0.0220
pixel brightness=0.88 AA threshold=0.0230
pixel brightness=0.89 AA threshold=0.0240
pixel brightness=0.90 AA threshold=0.0250
pixel brightness=0.91 AA threshold=0.0265
pixel brightness=0.92 AA threshold=0.0280
pixel brightness=0.93 AA threshold=0.0295
pixel brightness=0.94 AA threshold=0.0310
pixel brightness=0.95 AA threshold=0.0325
pixel brightness=0.96 AA threshold=0.0340
pixel brightness=0.97 AA threshold=0.0355
pixel brightness=0.98 AA threshold=0.0370
pixel brightness=0.99 AA threshold=0.0385
pixel brightness=1.00 AA threshold=0.0400
pixel brightness=1.01 AA threshold=0.0420
pixel brightness=1.02 AA threshold=0.0440
pixel brightness=1.03 AA threshold=0.0460
pixel brightness=1.04 AA threshold=0.0480
pixel brightness=1.05 AA threshold=0.0500
pixel brightness=1.06 AA threshold=0.0520
pixel brightness=1.07 AA threshold=0.0540
pixel brightness=1.08 AA threshold=0.0560
pixel brightness=1.09 AA threshold=0.0580
pixel brightness=1.10 AA threshold=0.0600
pixel brightness=1.11 AA threshold=0.0620
pixel brightness=1.12 AA threshold=0.0640
pixel brightness=1.13 AA threshold=0.0660
pixel brightness=1.14 AA threshold=0.0680
pixel brightness=1.15 AA threshold=0.0700
pixel brightness=1.16 AA threshold=0.0720
pixel brightness=1.17 AA threshold=0.0740
pixel brightness=1.18 AA threshold=0.0760
pixel brightness=1.19 AA threshold=0.0780
pixel brightness=1.20 AA threshold=0.0800
pixel brightness=1.21 AA threshold=0.0807
pixel brightness=1.22 AA threshold=0.0815
pixel brightness=1.23 AA threshold=0.0822
pixel brightness=1.24 AA threshold=0.0830
pixel brightness=1.25 AA threshold=0.0837
pixel brightness=1.26 AA threshold=0.0845
pixel brightness=1.27 AA threshold=0.0852
pixel brightness=1.28 AA threshold=0.0860
pixel brightness=1.29 AA threshold=0.0867
pixel brightness=1.30 AA threshold=0.0875
pixel brightness=1.31 AA threshold=0.0882
pixel brightness=1.32 AA threshold=0.0890
pixel brightness=1.33 AA threshold=0.0897
pixel brightness=1.34 AA threshold=0.0905
pixel brightness=1.35 AA threshold=0.0912
pixel brightness=1.36 AA threshold=0.0920
pixel brightness=1.37 AA threshold=0.0927
pixel brightness=1.38 AA threshold=0.0935
pixel brightness=1.39 AA threshold=0.0942
pixel brightness=1.40 AA threshold=0.0950
pixel brightness=1.41 AA threshold=0.0951
pixel brightness=1.42 AA threshold=0.0952
pixel brightness=1.43 AA threshold=0.0954
pixel brightness=1.44 AA threshold=0.0955
pixel brightness=1.45 AA threshold=0.0956
pixel brightness=1.46 AA threshold=0.0957
pixel brightness=1.47 AA threshold=0.0959
pixel brightness=1.48 AA threshold=0.0960
pixel brightness=1.49 AA threshold=0.0961
pixel brightness=1.50 AA threshold=0.0962
pixel brightness=1.51 AA threshold=0.0964
pixel brightness=1.52 AA threshold=0.0965
pixel brightness=1.53 AA threshold=0.0966
pixel brightness=1.54 AA threshold=0.0967
pixel brightness=1.55 AA threshold=0.0969
pixel brightness=1.56 AA threshold=0.0970
pixel brightness=1.57 AA threshold=0.0971
pixel brightness=1.58 AA threshold=0.0972
pixel brightness=1.59 AA threshold=0.0974
pixel brightness=1.60 AA threshold=0.0975
pixel brightness=1.61 AA threshold=0.0976
pixel brightness=1.62 AA threshold=0.0978
pixel brightness=1.63 AA threshold=0.0979
pixel brightness=1.64 AA threshold=0.0980
pixel brightness=1.65 AA threshold=0.0981
pixel brightness=1.66 AA threshold=0.0983
pixel brightness=1.67 AA threshold=0.0984
pixel brightness=1.68 AA threshold=0.0985
pixel brightness=1.69 AA threshold=0.0986
pixel brightness=1.70 AA threshold=0.0988
pixel brightness=1.71 AA threshold=0.0989
pixel brightness=1.72 AA threshold=0.0990
pixel brightness=1.73 AA threshold=0.0991
pixel brightness=1.74 AA threshold=0.0993
pixel brightness=1.75 AA threshold=0.0994
pixel brightness=1.76 AA threshold=0.0995
pixel brightness=1.77 AA threshold=0.0996
pixel brightness=1.78 AA threshold=0.0997
pixel brightness=1.79 AA threshold=0.0999
pixel brightness=1.80 AA threshold=0.1000
pixel brightness=1.81 AA threshold=0.1000
pixel brightness=1.82 AA threshold=0.1000
pixel brightness=1.83 AA threshold=0.1000
pixel brightness=1.84 AA threshold=0.1000
pixel brightness=1.85 AA threshold=0.1000
pixel brightness=1.86 AA threshold=0.1000
pixel brightness=1.87 AA threshold=0.1000
pixel brightness=1.88 AA threshold=0.1000
pixel brightness=1.89 AA threshold=0.1000
pixel brightness=1.90 AA threshold=0.1000
pixel brightness=1.91 AA threshold=0.1000
pixel brightness=1.92 AA threshold=0.1000
pixel brightness=1.93 AA threshold=0.1000
pixel brightness=1.94 AA threshold=0.1000
pixel brightness=1.95 AA threshold=0.1000
pixel brightness=1.96 AA threshold=0.1000
pixel brightness=1.97 AA threshold=0.1000
pixel brightness=1.98 AA threshold=0.1000
pixel brightness=1.99 AA threshold=0.1000


Category:task» feature request


thanks David !!!! I have great expectations with this feature


Status:ready to commit» fixed

Fixed in v3.0.0-beta:


Status:fixed» closed

Closing as it was marked as "fixed" for 4 weeks without any further comments from users.


Status:closed» active

Reopened due to this comment in the Forum:


Status:active» needs review


I've checked and I cannot see anything wrong. In fact, the curve generated threshold is not 0 and it's easy to make an scene that proves it. However, it's true that with the current curve as specified the curve generated thresholds are really low.

I've attached a simple example .blend that shows how the threshold generated by curve is not really 0. The problem is that  the current curve makes it really low and therefore very sensitive to minor noise, especially in pixel brightness below 0.5


About the curve parameters you mentioned in the forum, please will you give a more detailed description of what parameters do you think should be implemented and how the curve should be generated based on them?



AttachmentSize 69.25 KB


Hi David, thanks for looking into this. I can see how noise makes the algorithm much more sensitive since it is probably taking the darkest pixel in a montecarlo variation as a reference. In areas with lot of variation between bright and dark pixels this poses a problem. I guess that the only way to make it work is to set average brightness within several pixels around a camera ray but this means creating a whole new algorithm possibly with new memory structures, overhead and compatibility issues. Also we don't have an algorithm capable of telling apart montecarlo noise from geometry and textures aliasing. It is a really interesting problem to solve.

However, I can not emphasise enough how good would be that implement something like this. We would make YafaRay much more predictable by setting a target pass in which the whole image would get sampled as required and there would be a limited amount of wasted rays.




About making it more flexible, at the moment I would concentrate on making it working with the proposed curve, but in the medium term I think the best way is to make it flexible and more intuitive by setting the curve parameters (high medium and low tones) in a graphical windows against a image histogram.


Status:needs review» needs work


I'm starting to do some tests with some ideas to better detect noise and resample the noisy areas. I will keep you informed of my progress.


Status:needs work» postponed


Version:» <none>
Component:Code» YafaRay Core


this paper could be of interest

2009_stopping.pdf 2.45 MB


Hi, yes it looks nice. I will try this! Thanks!