diff options
Diffstat (limited to 'intern/cycles/kernel/kernel_random.h')
-rw-r--r-- | intern/cycles/kernel/kernel_random.h | 294 |
1 files changed, 142 insertions, 152 deletions
diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h index 61ddf4a4f81..6779c1f7160 100644 --- a/intern/cycles/kernel/kernel_random.h +++ b/intern/cycles/kernel/kernel_random.h @@ -23,7 +23,6 @@ CCL_NAMESPACE_BEGIN * this single threaded on a CPU for repeatable results. */ //#define __DEBUG_CORRELATION__ - /* High Dimensional Sobol. * * Multidimensional sobol with generator matrices. Dimension 0 and 1 are equal @@ -36,136 +35,138 @@ CCL_NAMESPACE_BEGIN * progressive pattern that doesn't suffer from this problem, because even * with this offset some dimensions are quite poor. */ -#define SOBOL_SKIP 64 +# define SOBOL_SKIP 64 ccl_device uint sobol_dimension(KernelGlobals *kg, int index, int dimension) { - uint result = 0; - uint i = index + SOBOL_SKIP; - for(uint j = 0; i; i >>= 1, j++) { - if(i & 1) { - result ^= kernel_tex_fetch(__sobol_directions, 32*dimension + j); - } - } - return result; + uint result = 0; + uint i = index + SOBOL_SKIP; + for (uint j = 0; i; i >>= 1, j++) { + if (i & 1) { + result ^= kernel_tex_fetch(__sobol_directions, 32 * dimension + j); + } + } + return result; } -#endif /* __SOBOL__ */ - +#endif /* __SOBOL__ */ -ccl_device_forceinline float path_rng_1D(KernelGlobals *kg, - uint rng_hash, - int sample, int num_samples, - int dimension) +ccl_device_forceinline float path_rng_1D( + KernelGlobals *kg, uint rng_hash, int sample, int num_samples, int dimension) { #ifdef __DEBUG_CORRELATION__ - return (float)drand48(); + return (float)drand48(); #endif #ifdef __CMJ__ # ifdef __SOBOL__ - if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ) + if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ) # endif - { - /* Correlated multi-jitter. */ - int p = rng_hash + dimension; - return cmj_sample_1D(sample, num_samples, p); - } + { + /* Correlated multi-jitter. */ + int p = rng_hash + dimension; + return cmj_sample_1D(sample, num_samples, p); + } #endif #ifdef __SOBOL__ - /* Sobol sequence value using direction vectors. */ - uint result = sobol_dimension(kg, sample, dimension); - float r = (float)result * (1.0f/(float)0xFFFFFFFF); + /* Sobol sequence value using direction vectors. */ + uint result = sobol_dimension(kg, sample, dimension); + float r = (float)result * (1.0f / (float)0xFFFFFFFF); - /* Cranly-Patterson rotation using rng seed */ - float shift; + /* Cranly-Patterson rotation using rng seed */ + float shift; - /* Hash rng with dimension to solve correlation issues. - * See T38710, T50116. - */ - uint tmp_rng = cmj_hash_simple(dimension, rng_hash); - shift = tmp_rng * (1.0f/(float)0xFFFFFFFF); + /* Hash rng with dimension to solve correlation issues. + * See T38710, T50116. + */ + uint tmp_rng = cmj_hash_simple(dimension, rng_hash); + shift = tmp_rng * (1.0f / (float)0xFFFFFFFF); - return r + shift - floorf(r + shift); + return r + shift - floorf(r + shift); #endif } ccl_device_forceinline void path_rng_2D(KernelGlobals *kg, uint rng_hash, - int sample, int num_samples, + int sample, + int num_samples, int dimension, - float *fx, float *fy) + float *fx, + float *fy) { #ifdef __DEBUG_CORRELATION__ - *fx = (float)drand48(); - *fy = (float)drand48(); - return; + *fx = (float)drand48(); + *fy = (float)drand48(); + return; #endif #ifdef __CMJ__ # ifdef __SOBOL__ - if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ) + if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ) # endif - { - /* Correlated multi-jitter. */ - int p = rng_hash + dimension; - cmj_sample_2D(sample, num_samples, p, fx, fy); - return; - } + { + /* Correlated multi-jitter. */ + int p = rng_hash + dimension; + cmj_sample_2D(sample, num_samples, p, fx, fy); + return; + } #endif #ifdef __SOBOL__ - /* Sobol. */ - *fx = path_rng_1D(kg, rng_hash, sample, num_samples, dimension); - *fy = path_rng_1D(kg, rng_hash, sample, num_samples, dimension + 1); + /* Sobol. */ + *fx = path_rng_1D(kg, rng_hash, sample, num_samples, dimension); + *fy = path_rng_1D(kg, rng_hash, sample, num_samples, dimension + 1); #endif } ccl_device_inline void path_rng_init(KernelGlobals *kg, - int sample, int num_samples, + int sample, + int num_samples, uint *rng_hash, - int x, int y, - float *fx, float *fy) + int x, + int y, + float *fx, + float *fy) { - /* load state */ - *rng_hash = hash_int_2d(x, y); - *rng_hash ^= kernel_data.integrator.seed; + /* load state */ + *rng_hash = hash_int_2d(x, y); + *rng_hash ^= kernel_data.integrator.seed; #ifdef __DEBUG_CORRELATION__ - srand48(*rng_hash + sample); + srand48(*rng_hash + sample); #endif - if(sample == 0) { - *fx = 0.5f; - *fy = 0.5f; - } - else { - path_rng_2D(kg, *rng_hash, sample, num_samples, PRNG_FILTER_U, fx, fy); - } + if (sample == 0) { + *fx = 0.5f; + *fy = 0.5f; + } + else { + path_rng_2D(kg, *rng_hash, sample, num_samples, PRNG_FILTER_U, fx, fy); + } } /* Linear Congruential Generator */ ccl_device uint lcg_step_uint(uint *rng) { - /* implicit mod 2^32 */ - *rng = (1103515245*(*rng) + 12345); - return *rng; + /* implicit mod 2^32 */ + *rng = (1103515245 * (*rng) + 12345); + return *rng; } ccl_device float lcg_step_float(uint *rng) { - /* implicit mod 2^32 */ - *rng = (1103515245*(*rng) + 12345); - return (float)*rng * (1.0f/(float)0xFFFFFFFF); + /* implicit mod 2^32 */ + *rng = (1103515245 * (*rng) + 12345); + return (float)*rng * (1.0f / (float)0xFFFFFFFF); } ccl_device uint lcg_init(uint seed) { - uint rng = seed; - lcg_step_uint(&rng); - return rng; + uint rng = seed; + lcg_step_uint(&rng); + return rng; } /* Path Tracing Utility Functions @@ -181,118 +182,107 @@ ccl_device_inline float path_state_rng_1D(KernelGlobals *kg, const ccl_addr_space PathState *state, int dimension) { - return path_rng_1D(kg, - state->rng_hash, - state->sample, state->num_samples, - state->rng_offset + dimension); + return path_rng_1D( + kg, state->rng_hash, state->sample, state->num_samples, state->rng_offset + dimension); } -ccl_device_inline void path_state_rng_2D(KernelGlobals *kg, - const ccl_addr_space PathState *state, - int dimension, - float *fx, float *fy) +ccl_device_inline void path_state_rng_2D( + KernelGlobals *kg, const ccl_addr_space PathState *state, int dimension, float *fx, float *fy) { - path_rng_2D(kg, - state->rng_hash, - state->sample, state->num_samples, - state->rng_offset + dimension, - fx, fy); + path_rng_2D(kg, + state->rng_hash, + state->sample, + state->num_samples, + state->rng_offset + dimension, + fx, + fy); } ccl_device_inline float path_state_rng_1D_hash(KernelGlobals *kg, - const ccl_addr_space PathState *state, - uint hash) + const ccl_addr_space PathState *state, + uint hash) { - /* Use a hash instead of dimension, this is not great but avoids adding - * more dimensions to each bounce which reduces quality of dimensions we - * are already using. */ - return path_rng_1D(kg, - cmj_hash_simple(state->rng_hash, hash), - state->sample, state->num_samples, - state->rng_offset); + /* Use a hash instead of dimension, this is not great but avoids adding + * more dimensions to each bounce which reduces quality of dimensions we + * are already using. */ + return path_rng_1D(kg, + cmj_hash_simple(state->rng_hash, hash), + state->sample, + state->num_samples, + state->rng_offset); } -ccl_device_inline float path_branched_rng_1D( - KernelGlobals *kg, - uint rng_hash, - const ccl_addr_space PathState *state, - int branch, - int num_branches, - int dimension) +ccl_device_inline float path_branched_rng_1D(KernelGlobals *kg, + uint rng_hash, + const ccl_addr_space PathState *state, + int branch, + int num_branches, + int dimension) { - return path_rng_1D(kg, - rng_hash, - state->sample * num_branches + branch, - state->num_samples * num_branches, - state->rng_offset + dimension); + return path_rng_1D(kg, + rng_hash, + state->sample * num_branches + branch, + state->num_samples * num_branches, + state->rng_offset + dimension); } -ccl_device_inline void path_branched_rng_2D( - KernelGlobals *kg, - uint rng_hash, - const ccl_addr_space PathState *state, - int branch, - int num_branches, - int dimension, - float *fx, float *fy) +ccl_device_inline void path_branched_rng_2D(KernelGlobals *kg, + uint rng_hash, + const ccl_addr_space PathState *state, + int branch, + int num_branches, + int dimension, + float *fx, + float *fy) { - path_rng_2D(kg, - rng_hash, - state->sample * num_branches + branch, - state->num_samples * num_branches, - state->rng_offset + dimension, - fx, fy); + path_rng_2D(kg, + rng_hash, + state->sample * num_branches + branch, + state->num_samples * num_branches, + state->rng_offset + dimension, + fx, + fy); } /* Utitility functions to get light termination value, * since it might not be needed in many cases. */ -ccl_device_inline float path_state_rng_light_termination( - KernelGlobals *kg, - const ccl_addr_space PathState *state) +ccl_device_inline float path_state_rng_light_termination(KernelGlobals *kg, + const ccl_addr_space PathState *state) { - if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) { - return path_state_rng_1D(kg, state, PRNG_LIGHT_TERMINATE); - } - return 0.0f; + if (kernel_data.integrator.light_inv_rr_threshold > 0.0f) { + return path_state_rng_1D(kg, state, PRNG_LIGHT_TERMINATE); + } + return 0.0f; } -ccl_device_inline float path_branched_rng_light_termination( - KernelGlobals *kg, - uint rng_hash, - const ccl_addr_space PathState *state, - int branch, - int num_branches) +ccl_device_inline float path_branched_rng_light_termination(KernelGlobals *kg, + uint rng_hash, + const ccl_addr_space PathState *state, + int branch, + int num_branches) { - if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) { - return path_branched_rng_1D(kg, - rng_hash, - state, - branch, - num_branches, - PRNG_LIGHT_TERMINATE); - } - return 0.0f; + if (kernel_data.integrator.light_inv_rr_threshold > 0.0f) { + return path_branched_rng_1D(kg, rng_hash, state, branch, num_branches, PRNG_LIGHT_TERMINATE); + } + return 0.0f; } -ccl_device_inline uint lcg_state_init(PathState *state, - uint scramble) +ccl_device_inline uint lcg_state_init(PathState *state, uint scramble) { - return lcg_init(state->rng_hash + state->rng_offset + state->sample*scramble); + return lcg_init(state->rng_hash + state->rng_offset + state->sample * scramble); } -ccl_device_inline uint lcg_state_init_addrspace(ccl_addr_space PathState *state, - uint scramble) +ccl_device_inline uint lcg_state_init_addrspace(ccl_addr_space PathState *state, uint scramble) { - return lcg_init(state->rng_hash + state->rng_offset + state->sample*scramble); + return lcg_init(state->rng_hash + state->rng_offset + state->sample * scramble); } - ccl_device float lcg_step_float_addrspace(ccl_addr_space uint *rng) { - /* Implicit mod 2^32 */ - *rng = (1103515245*(*rng) + 12345); - return (float)*rng * (1.0f/(float)0xFFFFFFFF); + /* Implicit mod 2^32 */ + *rng = (1103515245 * (*rng) + 12345); + return (float)*rng * (1.0f / (float)0xFFFFFFFF); } CCL_NAMESPACE_END |