Cycles: enable adaptive sampling for Sobol-Burley
This uses the same sample classification approach as used for PMJ, because it turns out to also work equally well with Sobol-Burley. This also implements a fallback (random classification) that should work "okay" for other samplers, though there are no other samplers at the moment. Differential Revision: https://developer.blender.org/D15845
This commit is contained in:
parent
4bbbba5bc2
commit
49ca810bf3
|
@ -296,7 +296,6 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
|
|||
row.prop(cscene, "use_animated_seed", text="", icon='TIME')
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = not (cscene.use_adaptive_sampling and cscene.use_preview_adaptive_sampling)
|
||||
col.prop(cscene, "sampling_pattern", text="Pattern")
|
||||
|
||||
col = layout.column(align=True)
|
||||
|
|
|
@ -147,16 +147,16 @@ ccl_device void film_write_adaptive_buffer(KernelGlobals kg,
|
|||
const Spectrum contribution,
|
||||
ccl_global float *ccl_restrict buffer)
|
||||
{
|
||||
/* Adaptive Sampling. Fill the additional buffer with the odd samples and calculate our stopping
|
||||
* criteria. This is the heuristic from "A hierarchical automatic stopping condition for Monte
|
||||
* Carlo global illumination" except that here it is applied per pixel and not in hierarchical
|
||||
* tiles. */
|
||||
/* Adaptive Sampling. Fill the additional buffer with only one half of the samples and
|
||||
* calculate our stopping criteria. This is the heuristic from "A hierarchical automatic
|
||||
* stopping condition for Monte Carlo global illumination" except that here it is applied
|
||||
* per pixel and not in hierarchical tiles. */
|
||||
|
||||
if (kernel_data.film.pass_adaptive_aux_buffer == PASS_UNUSED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sample_is_even(kernel_data.integrator.sampling_pattern, sample)) {
|
||||
if (sample_is_class_A(kernel_data.integrator.sampling_pattern, sample)) {
|
||||
const float3 contribution_rgb = spectrum_to_rgb(contribution);
|
||||
|
||||
film_write_pass_float4(buffer + kernel_data.film.pass_adaptive_aux_buffer,
|
||||
|
|
|
@ -90,18 +90,31 @@ ccl_device_inline uint path_rng_hash_init(KernelGlobals kg,
|
|||
return rng_hash;
|
||||
}
|
||||
|
||||
ccl_device_inline bool sample_is_even(int pattern, int sample)
|
||||
/**
|
||||
* Splits samples into two different classes, A and B, which can be
|
||||
* compared for variance estimation.
|
||||
*/
|
||||
ccl_device_inline bool sample_is_class_A(int pattern, int sample)
|
||||
{
|
||||
if (pattern == SAMPLING_PATTERN_PMJ) {
|
||||
/* See Section 10.2.1, "Progressive Multi-Jittered Sample Sequences", Christensen et al.
|
||||
* We can use this to get divide sample sequence into two classes for easier variance
|
||||
* estimation. */
|
||||
return popcount(uint(sample) & 0xaaaaaaaa) & 1;
|
||||
#if 0
|
||||
if (!(pattern == SAMPLING_PATTERN_PMJ || pattern == SAMPLING_PATTERN_SOBOL_BURLEY)) {
|
||||
/* Fallback: assign samples randomly.
|
||||
* This is guaranteed to work "okay" for any sampler, but isn't good.
|
||||
* (Note: the seed constant is just a random number to guard against
|
||||
* possible interactions with other uses of the hash. There's nothing
|
||||
* special about it.)
|
||||
*/
|
||||
return hash_hp_seeded_uint(sample, 0xa771f873) & 1;
|
||||
}
|
||||
else {
|
||||
/* TODO(Stefan): Are there reliable ways of dividing Sobol-Burley into two classes? */
|
||||
return sample & 0x1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This follows the approach from section 10.2.1 of "Progressive
|
||||
* Multi-Jittered Sample Sequences" by Christensen et al., but
|
||||
* implemented with efficient bit-fiddling.
|
||||
*
|
||||
* This approach also turns out to work equally well with Sobol-Burley
|
||||
* (see https://developer.blender.org/D15746#429471).
|
||||
*/
|
||||
return popcount(uint(sample) & 0xaaaaaaaa) & 1;
|
||||
}
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -217,9 +217,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
|||
FLT_MAX :
|
||||
sample_clamp_indirect * 3.0f;
|
||||
|
||||
/* Adaptive sampling requires PMJ, see sample_is_even. */
|
||||
kintegrator->sampling_pattern = (use_adaptive_sampling) ? SAMPLING_PATTERN_PMJ :
|
||||
sampling_pattern;
|
||||
kintegrator->sampling_pattern = sampling_pattern;
|
||||
kintegrator->scrambling_distance = scrambling_distance;
|
||||
|
||||
if (light_sampling_threshold > 0.0f) {
|
||||
|
|
Loading…
Reference in New Issue