This is the result of a rewrite of the adaptive sampling part of T38401, although there are large changes in some parts.
The major changes are:
- The Warmup Samples parameter was added again, as it helps the adaptive distribution in some cases
- All options are only available in experimental mode
- An Error-Progressive mode was added: Instead of sampling every tile until its error is low enough, every tile is rendered for the warmup interval, and afterwards the acquire_tile always returns the tile with the worst error (with num_samples equal to the map interval) until every tile is below the error threshold. This gives the same result as non-progressive adaptive stopping and the added overhead is negligible: In my test, 3:07.54 with progressive vs. 3:06.12 without progressive. It's enabled by setting a stopping threshold while progressive rendering is used.
- Working remaining time estimation: For non-progressive stopping, it relies only on the number of rendered tiles since the samples per tile may vary, while for progressive stopping the 1/sqrt(N) convergence of the error is used. It's not perfect, but usually, after 10% of the rendering time, the remaining time is within ~20% of the true value.
- The occasional freezing/stopping is resolved.
- When adaptive distribution is used, pixels might be processed by more than one thread, so in this case atomic operations are used for writing the passes (the CPU code has intrinsics for GCC, Clang, ICC and MSVC)
- A better TVI curve is used, so that now dark areas are no longer oversampled in comparison to bright areas
- The error value is scaled so that an error of 1 corresponds to "appears nearly noise-free if you don't zoom in"
- A bilateral blur is now used for building the importance map for adaptive distributing after the gaussian blur, which helps in areas with single noisy pixels instead of uniformly noisy pixels (for example, the edge of the light reflection in the BMW scene). Thanks to @Adam Friesen (ace_dragon) for the idea!
As a summary of T38401, the features this patch adds are:
- Adaptive stopping: If you set the stopping threshold to a value >0, this mode is activated. For every tile, the remaining error is estimated after a certain number of samples, controlled by the "map interval". The error exponent controls how sensitive the estimation is to outliers: The higher it gets, the more a single noisy spot influences the error value of the tile (it should stay between 2 and ~15). Once the error is below the threshold, the tile is stopped. In case the maximum amount of samples per tile is reached, the tile stops as well, even if the threshold is not reached yet. This does not affect the individual pixels in the tile, that's what adaptive distribution is for.
- Error-progressive mode: See 3. above
- Adaptive distribution: If this option is enabled, the samples inside every tile are also distributed accordingly to noise levels. Once the warmup interval is over, an importance map is generated and samples are drawn from it (this happens on the CPU even for GPU rendering). This helps mainly for big tiles (usually >32x32) with different levels of noise, for example, at the edge between scene and background. If this is used without adaptive stopping, every tile will still receive the same amount of samples in total.
The OpenCL code is untested, but is basically identical to the CUDA code, which works perfectly.
Please keep this revision clean from comments which are not directly related to the code review process. Users feedback and questions shouldn't be asked here. This is a developers tool for core review, long discussions here only makes it so crucial info is not noticed. We don't have time to read all the comments.
Thanks for understanding.