diff options
Diffstat (limited to 'intern/cycles/kernel/sample')
-rw-r--r-- | intern/cycles/kernel/sample/jitter.h | 61 | ||||
-rw-r--r-- | intern/cycles/kernel/sample/pattern.h | 18 | ||||
-rw-r--r-- | intern/cycles/kernel/sample/sobol_burley.h | 78 |
3 files changed, 75 insertions, 82 deletions
diff --git a/intern/cycles/kernel/sample/jitter.h b/intern/cycles/kernel/sample/jitter.h index 6a9ff1beec5..e748f95fc7d 100644 --- a/intern/cycles/kernel/sample/jitter.h +++ b/intern/cycles/kernel/sample/jitter.h @@ -7,7 +7,10 @@ #pragma once CCL_NAMESPACE_BEGIN -ccl_device float pmj_sample_1D(KernelGlobals kg, uint sample, uint rng_hash, uint dimension) +ccl_device float pmj_sample_1D(KernelGlobals kg, + uint sample, + const uint rng_hash, + const uint dimension) { uint seed = rng_hash; @@ -22,20 +25,22 @@ ccl_device float pmj_sample_1D(KernelGlobals kg, uint sample, uint rng_hash, uin * The funky sample mask stuff is to ensure that we only shuffle * *within* the current sample pattern, which is necessary to avoid * early repeat pattern use. */ - uint pattern_i = hash_shuffle_uint(dimension, NUM_PMJ_PATTERNS, seed); + const uint pattern_i = hash_shuffle_uint(dimension, NUM_PMJ_PATTERNS, seed); /* NUM_PMJ_SAMPLES should be a power of two, so this results in a mask. */ - uint sample_mask = NUM_PMJ_SAMPLES - 1; - uint sample_shuffled = nested_uniform_scramble(sample, hash_wang_seeded_uint(dimension, seed)); + const uint sample_mask = NUM_PMJ_SAMPLES - 1; + const uint sample_shuffled = nested_uniform_scramble(sample, + hash_wang_seeded_uint(dimension, seed)); sample = (sample & ~sample_mask) | (sample_shuffled & sample_mask); /* Fetch the sample. */ - uint index = ((pattern_i * NUM_PMJ_SAMPLES) + sample) % (NUM_PMJ_SAMPLES * NUM_PMJ_PATTERNS); + const uint index = ((pattern_i * NUM_PMJ_SAMPLES) + sample) % + (NUM_PMJ_SAMPLES * NUM_PMJ_PATTERNS); float x = kernel_data_fetch(sample_pattern_lut, index * 2); /* Do limited Cranley-Patterson rotation when using scrambling distance. */ if (kernel_data.integrator.scrambling_distance < 1.0f) { - float jitter_x = hash_wang_seeded_float(dimension, rng_hash) * - kernel_data.integrator.scrambling_distance; + const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) * + kernel_data.integrator.scrambling_distance; x += jitter_x; x -= floorf(x); } @@ -43,12 +48,10 @@ ccl_device float pmj_sample_1D(KernelGlobals kg, uint sample, uint rng_hash, uin return x; } -ccl_device void pmj_sample_2D(KernelGlobals kg, - uint sample, - uint rng_hash, - uint dimension, - ccl_private float *x, - ccl_private float *y) +ccl_device float2 pmj_sample_2D(KernelGlobals kg, + uint sample, + const uint rng_hash, + const uint dimension) { uint seed = rng_hash; @@ -63,28 +66,32 @@ ccl_device void pmj_sample_2D(KernelGlobals kg, * The funky sample mask stuff is to ensure that we only shuffle * *within* the current sample pattern, which is necessary to avoid * early repeat pattern use. */ - uint pattern_i = hash_shuffle_uint(dimension, NUM_PMJ_PATTERNS, seed); + const uint pattern_i = hash_shuffle_uint(dimension, NUM_PMJ_PATTERNS, seed); /* NUM_PMJ_SAMPLES should be a power of two, so this results in a mask. */ - uint sample_mask = NUM_PMJ_SAMPLES - 1; - uint sample_shuffled = nested_uniform_scramble(sample, hash_wang_seeded_uint(dimension, seed)); + const uint sample_mask = NUM_PMJ_SAMPLES - 1; + const uint sample_shuffled = nested_uniform_scramble(sample, + hash_wang_seeded_uint(dimension, seed)); sample = (sample & ~sample_mask) | (sample_shuffled & sample_mask); /* Fetch the sample. */ - uint index = ((pattern_i * NUM_PMJ_SAMPLES) + sample) % (NUM_PMJ_SAMPLES * NUM_PMJ_PATTERNS); - (*x) = kernel_data_fetch(sample_pattern_lut, index * 2); - (*y) = kernel_data_fetch(sample_pattern_lut, index * 2 + 1); + const uint index = ((pattern_i * NUM_PMJ_SAMPLES) + sample) % + (NUM_PMJ_SAMPLES * NUM_PMJ_PATTERNS); + float x = kernel_data_fetch(sample_pattern_lut, index * 2); + float y = kernel_data_fetch(sample_pattern_lut, index * 2 + 1); /* Do limited Cranley-Patterson rotation when using scrambling distance. */ if (kernel_data.integrator.scrambling_distance < 1.0f) { - float jitter_x = hash_wang_seeded_float(dimension, rng_hash) * - kernel_data.integrator.scrambling_distance; - float jitter_y = hash_wang_seeded_float(dimension, rng_hash ^ 0xca0e1151) * - kernel_data.integrator.scrambling_distance; - (*x) += jitter_x; - (*y) += jitter_y; - (*x) -= floorf(*x); - (*y) -= floorf(*y); + const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) * + kernel_data.integrator.scrambling_distance; + const float jitter_y = hash_wang_seeded_float(dimension, rng_hash ^ 0xca0e1151) * + kernel_data.integrator.scrambling_distance; + x += jitter_x; + y += jitter_y; + x -= floorf(x); + y -= floorf(y); } + + return make_float2(x, y); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/sample/pattern.h b/intern/cycles/kernel/sample/pattern.h index cc5d0e960ec..6477e29fa40 100644 --- a/intern/cycles/kernel/sample/pattern.h +++ b/intern/cycles/kernel/sample/pattern.h @@ -30,24 +30,20 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals kg, } } -ccl_device_forceinline void path_rng_2D(KernelGlobals kg, - uint rng_hash, - int sample, - int dimension, - ccl_private float *fx, - ccl_private float *fy) +ccl_device_forceinline float2 path_rng_2D(KernelGlobals kg, + uint rng_hash, + int sample, + int dimension) { #ifdef __DEBUG_CORRELATION__ - *fx = (float)drand48(); - *fy = (float)drand48(); - return; + return make_float2((float)drand48(), (float)drand48()); #endif if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) { - sobol_burley_sample_2D(sample, dimension, rng_hash, fx, fy); + return sobol_burley_sample_2D(sample, dimension, rng_hash); } else { - pmj_sample_2D(kg, sample, rng_hash, dimension, fx, fy); + return pmj_sample_2D(kg, sample, rng_hash, dimension); } } diff --git a/intern/cycles/kernel/sample/sobol_burley.h b/intern/cycles/kernel/sample/sobol_burley.h index 4e041aa075e..47796ae7998 100644 --- a/intern/cycles/kernel/sample/sobol_burley.h +++ b/intern/cycles/kernel/sample/sobol_burley.h @@ -32,14 +32,16 @@ CCL_NAMESPACE_BEGIN * Note that the seed must be well randomized before being * passed to this function. */ -ccl_device_forceinline float sobol_burley(uint rev_bit_index, uint dimension, uint scramble_seed) +ccl_device_forceinline float sobol_burley(uint rev_bit_index, + const uint dimension, + const uint scramble_seed) { uint result = 0; if (dimension == 0) { - // Fast-path for dimension 0, which is just Van der corput. - // This makes a notable difference in performance since we reuse - // dimensions for padding, and dimension 0 is reused the most. + /* Fast-path for dimension 0, which is just Van der corput. + * This makes a notable difference in performance since we reuse + * dimensions for padding, and dimension 0 is reused the most. */ result = reverse_integer_bits(rev_bit_index); } else { @@ -49,14 +51,14 @@ ccl_device_forceinline float sobol_burley(uint rev_bit_index, uint dimension, ui result ^= sobol_burley_table[dimension][i + j]; i += j + 1; - // We can't do "<<= j + 1" because that can overflow the shift - // operator, which doesn't do what we need on at least x86. + /* We can't do "<<= j + 1" because that can overflow the shift + * operator, which doesn't do what we need on at least x86. */ rev_bit_index <<= j; rev_bit_index <<= 1; } } - // Apply Owen scrambling. + /* Apply Owen scrambling. */ result = reverse_integer_bits(reversed_bit_owen(result, scramble_seed)); return uint_to_float_excl(result); @@ -65,13 +67,13 @@ ccl_device_forceinline float sobol_burley(uint rev_bit_index, uint dimension, ui /* * Computes a 1D Owen-scrambled and shuffled Sobol sample. */ -ccl_device float sobol_burley_sample_1D(uint index, uint dimension, uint seed) +ccl_device float sobol_burley_sample_1D(uint index, uint const dimension, uint seed) { - // Include the dimension in the seed, so we get decorrelated - // sequences for different dimensions via shuffling. + /* Include the dimension in the seed, so we get decorrelated + * sequences for different dimensions via shuffling. */ seed ^= hash_hp_uint(dimension); - // Shuffle. + /* Shuffle. */ index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xbff95bfe); return sobol_burley(index, 0, seed ^ 0x635c77bd); @@ -80,64 +82,52 @@ ccl_device float sobol_burley_sample_1D(uint index, uint dimension, uint seed) /* * Computes a 2D Owen-scrambled and shuffled Sobol sample. */ -ccl_device void sobol_burley_sample_2D( - uint index, uint dimension_set, uint seed, ccl_private float *x, ccl_private float *y) +ccl_device float2 sobol_burley_sample_2D(uint index, const uint dimension_set, uint seed) { - // Include the dimension set in the seed, so we get decorrelated - // sequences for different dimension sets via shuffling. + /* Include the dimension set in the seed, so we get decorrelated + * sequences for different dimension sets via shuffling. */ seed ^= hash_hp_uint(dimension_set); - // Shuffle. + /* Shuffle. */ index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xf8ade99a); - *x = sobol_burley(index, 0, seed ^ 0xe0aaaf76); - *y = sobol_burley(index, 1, seed ^ 0x94964d4e); + return make_float2(sobol_burley(index, 0, seed ^ 0xe0aaaf76), + sobol_burley(index, 1, seed ^ 0x94964d4e)); } /* * Computes a 3D Owen-scrambled and shuffled Sobol sample. */ -ccl_device void sobol_burley_sample_3D(uint index, - uint dimension_set, - uint seed, - ccl_private float *x, - ccl_private float *y, - ccl_private float *z) +ccl_device float3 sobol_burley_sample_3D(uint index, const uint dimension_set, uint seed) { - // Include the dimension set in the seed, so we get decorrelated - // sequences for different dimension sets via shuffling. + /* Include the dimension set in the seed, so we get decorrelated + * sequences for different dimension sets via shuffling. */ seed ^= hash_hp_uint(dimension_set); - // Shuffle. + /* Shuffle. */ index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xcaa726ac); - *x = sobol_burley(index, 0, seed ^ 0x9e78e391); - *y = sobol_burley(index, 1, seed ^ 0x67c33241); - *z = sobol_burley(index, 2, seed ^ 0x78c395c5); + return make_float3(sobol_burley(index, 0, seed ^ 0x9e78e391), + sobol_burley(index, 1, seed ^ 0x67c33241), + sobol_burley(index, 2, seed ^ 0x78c395c5)); } /* * Computes a 4D Owen-scrambled and shuffled Sobol sample. */ -ccl_device void sobol_burley_sample_4D(uint index, - uint dimension_set, - uint seed, - ccl_private float *x, - ccl_private float *y, - ccl_private float *z, - ccl_private float *w) +ccl_device float4 sobol_burley_sample_4D(uint index, const uint dimension_set, uint seed) { - // Include the dimension set in the seed, so we get decorrelated - // sequences for different dimension sets via shuffling. + /* Include the dimension set in the seed, so we get decorrelated + * sequences for different dimension sets via shuffling. */ seed ^= hash_hp_uint(dimension_set); - // Shuffle. + /* Shuffle. */ index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xc2c1a055); - *x = sobol_burley(index, 0, seed ^ 0x39468210); - *y = sobol_burley(index, 1, seed ^ 0xe9d8a845); - *z = sobol_burley(index, 2, seed ^ 0x5f32b482); - *w = sobol_burley(index, 3, seed ^ 0x1524cc56); + return make_float4(sobol_burley(index, 0, seed ^ 0x39468210), + sobol_burley(index, 1, seed ^ 0xe9d8a845), + sobol_burley(index, 2, seed ^ 0x5f32b482), + sobol_burley(index, 3, seed ^ 0x1524cc56)); } CCL_NAMESPACE_END |