diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 47907481b03..dfaae666785 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -290,11 +290,11 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel): col.active = not(cscene.use_adaptive_sampling) col.prop(cscene, "sampling_pattern", text="Pattern") col = layout.column(align=True) - col.active = cscene.sampling_pattern == 'SOBOL' and not cscene.use_adaptive_sampling + col.active = not cscene.use_adaptive_sampling col.prop(cscene, "scrambling_distance", text="Scrambling Distance Strength") col.prop(cscene, "adaptive_scrambling_distance", text="Adaptive Scrambling Distance") col = layout.column(align=True) - col.active = ((cscene.scrambling_distance < 1.0) or cscene.adaptive_scrambling_distance) and cscene.sampling_pattern == 'SOBOL' and not cscene.use_adaptive_sampling + col.active = ((cscene.scrambling_distance < 1.0) or cscene.adaptive_scrambling_distance) and not cscene.use_adaptive_sampling col.prop(cscene, "preview_scrambling_distance", text="Viewport Scrambling Distance") layout.separator() diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp index f6f490077a7..e0a13625962 100644 --- a/intern/cycles/blender/sync.cpp +++ b/intern/cycles/blender/sync.cpp @@ -340,14 +340,16 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background) cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_SOBOL); integrator->set_sampling_pattern(sampling_pattern); + bool use_adaptive_sampling = false; if (preview) { - integrator->set_use_adaptive_sampling( - RNA_boolean_get(&cscene, "use_preview_adaptive_sampling")); + use_adaptive_sampling = RNA_boolean_get(&cscene, "use_preview_adaptive_sampling"); + integrator->set_use_adaptive_sampling(use_adaptive_sampling); integrator->set_adaptive_threshold(get_float(cscene, "preview_adaptive_threshold")); integrator->set_adaptive_min_samples(get_int(cscene, "preview_adaptive_min_samples")); } else { - integrator->set_use_adaptive_sampling(RNA_boolean_get(&cscene, "use_adaptive_sampling")); + use_adaptive_sampling = RNA_boolean_get(&cscene, "use_adaptive_sampling"); + integrator->set_use_adaptive_sampling(use_adaptive_sampling); integrator->set_adaptive_threshold(get_float(cscene, "adaptive_threshold")); integrator->set_adaptive_min_samples(get_int(cscene, "adaptive_min_samples")); } @@ -361,7 +363,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background) /* only use scrambling distance in the viewport if user wants to and disable with AS */ bool preview_scrambling_distance = get_boolean(cscene, "preview_scrambling_distance"); - if ((preview && !preview_scrambling_distance) || sampling_pattern != SAMPLING_PATTERN_SOBOL) + if ((preview && !preview_scrambling_distance) || use_adaptive_sampling) scrambling_distance = 1.0f; VLOG(1) << "Used Scrambling Distance: " << scrambling_distance; diff --git a/intern/cycles/integrator/tile.cpp b/intern/cycles/integrator/tile.cpp index b49e1b27b83..4a1558cce09 100644 --- a/intern/cycles/integrator/tile.cpp +++ b/intern/cycles/integrator/tile.cpp @@ -74,39 +74,9 @@ TileSize tile_calculate_best_size(const int2 &image_size, TileSize tile_size; const int num_path_states_per_sample = max_num_path_states / num_samples; if (scrambling_distance < 0.9f) { - /* Prefer large tiles for scrambling distance. */ - if (image_size.x * image_size.y <= num_path_states_per_sample) { - tile_size.width = image_size.x; - tile_size.height = image_size.y; - } - else { - /* Pick the option with the biggest tile size */ - int heightOption = num_path_states_per_sample / image_size.x; - int widthOption = num_path_states_per_sample / image_size.y; - // Check if these options are possible - if ((heightOption > 0) || (widthOption > 0)) { - int area1 = image_size.x * heightOption; - int area2 = widthOption * image_size.y; - /* The option with the biggest pixel area */ - if (area1 >= area2) { - tile_size.width = image_size.x; - tile_size.height = heightOption; - } - else { - tile_size.width = widthOption; - tile_size.height = image_size.y; - } - } - else { // Large tiles are not an option so use square tiles - if (num_path_states_per_sample != 0) { - tile_size.width = round_down_to_power_of_two(lround(sqrt(num_path_states_per_sample))); - tile_size.height = tile_size.width; - } - else { - tile_size.width = tile_size.height = 1; - } - } - } + /* Prefer large tiles for scrambling distance, bounded by max num path states. */ + tile_size.width = min(image_size.x, max_num_path_states); + tile_size.height = min(image_size.y, max(max_num_path_states / tile_size.width, 1)); } else { /* Calculate tile size as if it is the most possible one to fit an entire range of samples. diff --git a/intern/cycles/kernel/sample/jitter.h b/intern/cycles/kernel/sample/jitter.h index b62ec7fda42..b76b9b8f23e 100644 --- a/intern/cycles/kernel/sample/jitter.h +++ b/intern/cycles/kernel/sample/jitter.h @@ -72,13 +72,27 @@ ccl_device_inline float cmj_randfloat_simple(uint i, uint p) return cmj_hash_simple(i, p) * (1.0f / (float)0xFFFFFFFF); } +ccl_device_inline float cmj_randfloat_simple_dist(uint i, uint p, float d) +{ + return cmj_hash_simple(i, p) * (d / (float)0xFFFFFFFF); +} + ccl_device float pmj_sample_1D(KernelGlobals kg, uint sample, uint rng_hash, uint dimension) { + uint hash = rng_hash; + float jitter_x = 0.0f; + if (kernel_data.integrator.scrambling_distance < 1.0f) { + hash = kernel_data.integrator.seed; + + jitter_x = cmj_randfloat_simple_dist( + dimension, rng_hash, kernel_data.integrator.scrambling_distance); + } + /* Perform Owen shuffle of the sample number to reorder the samples. */ #ifdef _SIMPLE_HASH_ - const uint rv = cmj_hash_simple(dimension, rng_hash); + const uint rv = cmj_hash_simple(dimension, hash); #else /* Use a _REGULAR_HASH_. */ - const uint rv = cmj_hash(dimension, rng_hash); + const uint rv = cmj_hash(dimension, hash); #endif #ifdef _XOR_SHUFFLE_ # warning "Using XOR shuffle." @@ -101,12 +115,12 @@ ccl_device float pmj_sample_1D(KernelGlobals kg, uint sample, uint rng_hash, uin #ifndef _NO_CRANLEY_PATTERSON_ROTATION_ /* Use Cranley-Patterson rotation to displace the sample pattern. */ # ifdef _SIMPLE_HASH_ - float dx = cmj_randfloat_simple(d, rng_hash); + float dx = cmj_randfloat_simple(d, hash); # else - float dx = cmj_randfloat(d, rng_hash); + float dx = cmj_randfloat(d, hash); # endif /* Jitter sample locations and map back into [0 1]. */ - fx = fx + dx; + fx = fx + dx + jitter_x; fx = fx - floorf(fx); #else # warning "Not using Cranley-Patterson Rotation." @@ -122,11 +136,23 @@ ccl_device void pmj_sample_2D(KernelGlobals kg, ccl_private float *x, ccl_private float *y) { + uint hash = rng_hash; + float jitter_x = 0.0f; + float jitter_y = 0.0f; + if (kernel_data.integrator.scrambling_distance < 1.0f) { + hash = kernel_data.integrator.seed; + + jitter_x = cmj_randfloat_simple_dist( + dimension, rng_hash, kernel_data.integrator.scrambling_distance); + jitter_y = cmj_randfloat_simple_dist( + dimension + 1, rng_hash, kernel_data.integrator.scrambling_distance); + } + /* Perform a shuffle on the sample number to reorder the samples. */ #ifdef _SIMPLE_HASH_ - const uint rv = cmj_hash_simple(dimension, rng_hash); + const uint rv = cmj_hash_simple(dimension, hash); #else /* Use a _REGULAR_HASH_. */ - const uint rv = cmj_hash(dimension, rng_hash); + const uint rv = cmj_hash(dimension, hash); #endif #ifdef _XOR_SHUFFLE_ # warning "Using XOR shuffle." @@ -137,7 +163,7 @@ ccl_device void pmj_sample_2D(KernelGlobals kg, /* Based on the sample number a sample pattern is selected and offset by the dimension. */ const uint sample_set = s / NUM_PMJ_SAMPLES; - const uint d = (dimension + sample_set); + const uint d = dimension + sample_set; uint dim = d % NUM_PMJ_PATTERNS; int index = 2 * (dim * NUM_PMJ_SAMPLES + (s % NUM_PMJ_SAMPLES)); @@ -147,15 +173,15 @@ ccl_device void pmj_sample_2D(KernelGlobals kg, #ifndef _NO_CRANLEY_PATTERSON_ROTATION_ /* Use Cranley-Patterson rotation to displace the sample pattern. */ # ifdef _SIMPLE_HASH_ - float dx = cmj_randfloat_simple(d, rng_hash); - float dy = cmj_randfloat_simple(d + 1, rng_hash); + float dx = cmj_randfloat_simple(d, hash); + float dy = cmj_randfloat_simple(d + 1, hash); # else - float dx = cmj_randfloat(d, rng_hash); - float dy = cmj_randfloat(d + 1, rng_hash); + float dx = cmj_randfloat(d, hash); + float dy = cmj_randfloat(d + 1, hash); # endif /* Jitter sample locations and map back to the unit square [0 1]x[0 1]. */ - float sx = fx + dx; - float sy = fy + dy; + float sx = fx + dx + jitter_x; + float sy = fy + dy + jitter_y; sx = sx - floorf(sx); sy = sy - floorf(sy); #else