Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r--intern/cycles/kernel/kernel_path_state.h2
-rw-r--r--intern/cycles/kernel/kernel_random.h13
-rw-r--r--intern/cycles/kernel/kernel_types.h1
-rw-r--r--intern/cycles/kernel/kernel_volume.h81
4 files changed, 61 insertions, 36 deletions
diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h
index 90937dbf86e..479bb22d780 100644
--- a/intern/cycles/kernel/kernel_path_state.h
+++ b/intern/cycles/kernel/kernel_path_state.h
@@ -60,8 +60,6 @@ ccl_device_inline void path_state_init(KernelGlobals *kg,
if(kernel_data.integrator.use_volumes) {
/* Initialize volume stack with volume we are inside of. */
kernel_volume_stack_init(kg, stack_sd, state, ray, state->volume_stack);
- /* Seed RNG for cases where we can't use stratified samples .*/
- state->rng_congruential = lcg_init(rng_hash + sample*0x51633e2d);
}
else {
state->volume_stack[0].shader = SHADER_NONE;
diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h
index efb9048beb8..93152e9ff1c 100644
--- a/intern/cycles/kernel/kernel_random.h
+++ b/intern/cycles/kernel/kernel_random.h
@@ -199,6 +199,19 @@ ccl_device_inline void path_state_rng_2D(KernelGlobals *kg,
fx, fy);
}
+ccl_device_inline float path_state_rng_1D_hash(KernelGlobals *kg,
+ 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);
+}
+
ccl_device_inline float path_branched_rng_1D(
KernelGlobals *kg,
uint rng_hash,
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 2945cdb4593..af1ecb05788 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -1107,7 +1107,6 @@ typedef struct PathState {
#ifdef __VOLUME__
int volume_bounce;
int volume_bounds_bounce;
- uint rng_congruential;
VolumeStack volume_stack[VOLUME_STACK_SIZE];
#endif
} PathState;
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index 88360e5f1ae..86378289b02 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -156,6 +156,24 @@ ccl_device int volume_stack_sampling_method(KernelGlobals *kg, VolumeStack *stac
return method;
}
+ccl_device_inline void kernel_volume_step_init(KernelGlobals *kg,
+ ccl_addr_space PathState *state,
+ float t,
+ float *step_size,
+ float *step_offset)
+{
+ const int max_steps = kernel_data.integrator.volume_max_steps;
+ float step = min(kernel_data.integrator.volume_step_size, t);
+
+ /* compute exact steps in advance for malloc */
+ if(t > max_steps * step) {
+ step = t / (float)max_steps;
+ }
+
+ *step_size = step;
+ *step_offset = path_state_rng_1D_hash(kg, state, 0x1e31d8a4) * step;
+}
+
/* Volume Shadows
*
* These functions are used to attenuate shadow rays to lights. Both absorption
@@ -188,8 +206,8 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg,
/* prepare for stepping */
int max_steps = kernel_data.integrator.volume_max_steps;
- float step = kernel_data.integrator.volume_step_size;
- float random_jitter_offset = lcg_step_float_addrspace(&state->rng_congruential) * step;
+ float step_offset, step_size;
+ kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
/* compute extinction at the start */
float t = 0.0f;
@@ -198,14 +216,15 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg,
for(int i = 0; i < max_steps; i++) {
/* advance to new position */
- float new_t = min(ray->t, (i+1) * step);
- float dt = new_t - t;
+ float new_t = min(ray->t, (i+1) * step_size);
- /* use random position inside this segment to sample shader */
- if(new_t == ray->t)
- random_jitter_offset = lcg_step_float_addrspace(&state->rng_congruential) * dt;
+ /* use random position inside this segment to sample shader, adjust
+ * for last step that is shorter than other steps. */
+ if(new_t == ray->t) {
+ step_offset *= (new_t - t) / step_size;
+ }
- float3 new_P = ray->P + ray->D * (t + random_jitter_offset);
+ float3 new_P = ray->P + ray->D * (t + step_offset);
float3 sigma_t;
/* compute attenuation over segment */
@@ -504,8 +523,8 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
/* prepare for stepping */
int max_steps = kernel_data.integrator.volume_max_steps;
- float step_size = kernel_data.integrator.volume_step_size;
- float random_jitter_offset = lcg_step_float_addrspace(&state->rng_congruential) * step_size;
+ float step_offset, step_size;
+ kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
/* compute coefficients at the start */
float t = 0.0f;
@@ -522,11 +541,13 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
float new_t = min(ray->t, (i+1) * step_size);
float dt = new_t - t;
- /* use random position inside this segment to sample shader */
- if(new_t == ray->t)
- random_jitter_offset = lcg_step_float_addrspace(&state->rng_congruential) * dt;
+ /* use random position inside this segment to sample shader,
+ * for last shorter step we remap it to fit within the segment. */
+ if(new_t == ray->t) {
+ step_offset *= (new_t - t) / step_size;
+ }
- float3 new_P = ray->P + ray->D * (t + random_jitter_offset);
+ float3 new_P = ray->P + ray->D * (t + step_offset);
VolumeShaderCoefficients coeff;
/* compute segment */
@@ -694,19 +715,12 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
/* prepare for volume stepping */
int max_steps;
- float step_size, random_jitter_offset;
+ float step_size, step_offset;
if(heterogeneous) {
- const int global_max_steps = kernel_data.integrator.volume_max_steps;
- step_size = kernel_data.integrator.volume_step_size;
- /* compute exact steps in advance for malloc */
- if(ray->t > global_max_steps*step_size) {
- max_steps = global_max_steps;
- step_size = ray->t / (float)max_steps;
- }
- else {
- max_steps = max((int)ceilf(ray->t/step_size), 1);
- }
+ max_steps = kernel_data.integrator.volume_max_steps;
+ kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
+
#ifdef __KERNEL_CPU__
/* NOTE: For the branched path tracing it's possible to have direct
* and indirect light integration both having volume segments allocated.
@@ -723,19 +737,18 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
sizeof(*kg->decoupled_volume_steps));
if(kg->decoupled_volume_steps[index] == NULL) {
kg->decoupled_volume_steps[index] =
- (VolumeStep*)malloc(sizeof(VolumeStep)*global_max_steps);
+ (VolumeStep*)malloc(sizeof(VolumeStep)*max_steps);
}
segment->steps = kg->decoupled_volume_steps[index];
++kg->decoupled_volume_steps_index;
#else
segment->steps = (VolumeStep*)malloc(sizeof(VolumeStep)*max_steps);
#endif
- random_jitter_offset = lcg_step_float(&state->rng_congruential) * step_size;
}
else {
max_steps = 1;
step_size = ray->t;
- random_jitter_offset = 0.0f;
+ step_offset = 0.0f;
segment->steps = &segment->stack_step;
}
@@ -757,11 +770,13 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
float new_t = min(ray->t, (i+1) * step_size);
float dt = new_t - t;
- /* use random position inside this segment to sample shader */
- if(heterogeneous && new_t == ray->t)
- random_jitter_offset = lcg_step_float(&state->rng_congruential) * dt;
+ /* use random position inside this segment to sample shader,
+ * for last shorter step we remap it to fit within the segment. */
+ if(new_t == ray->t) {
+ step_offset *= (new_t - t) / step_size;
+ }
- float3 new_P = ray->P + ray->D * (t + random_jitter_offset);
+ float3 new_P = ray->P + ray->D * (t + step_offset);
VolumeShaderCoefficients coeff;
/* compute segment */
@@ -818,7 +833,7 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
step->accum_transmittance = accum_transmittance;
step->cdf_distance = cdf_distance;
step->t = new_t;
- step->shade_t = t + random_jitter_offset;
+ step->shade_t = t + step_offset;
/* stop if at the end of the volume */
t = new_t;