[Bf-blender-cvs] [22e3a4a] openvdb: Cycles: quick patch to support decoupled ray marching.
Kévin Dietrich
noreply at git.blender.org
Sun Jan 17 21:26:36 CET 2016
Commit: 22e3a4ad5ee3f3be274aadf5dfdc9098a4953959
Author: Kévin Dietrich
Date: Sun Jan 17 21:22:57 2016 +0100
Branches: openvdb
https://developer.blender.org/rB22e3a4ad5ee3f3be274aadf5dfdc9098a4953959
Cycles: quick patch to support decoupled ray marching.
Rendering is not quite right, lots of black spots and areas, but at
least it's working.
===================================================================
M intern/cycles/kernel/kernel_volume.h
===================================================================
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index ff35450..5020a64 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -761,85 +761,180 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
float3 accum_emission = make_float3(0.0f, 0.0f, 0.0f);
float3 accum_transmittance = make_float3(1.0f, 1.0f, 1.0f);
float3 cdf_distance = make_float3(0.0f, 0.0f, 0.0f);
- float t = 0.0f;
+ float t = 0.0f, t1 = 0.0f;
segment->numsteps = 0;
segment->closure_flag = 0;
bool is_last_step_empty = false;
VolumeStep *step = segment->steps;
+#ifdef __OPENVDB__
+ int vdb_index = kernel_data.tables.density_index;
+ bool has_vdb_volume = kernel_data.tables.num_volumes > 0;
- for(int i = 0; i < max_steps; i++, step++) {
- /* advance to new position */
- float new_t = min(ray->t, (i+1) * step_size);
- float dt = new_t - t;
+ if(has_vdb_volume && kg->float_volumes[vdb_index]->has_uniform_voxels()) {
+ /* TODO(kevin): this call should be moved out of here, all it does is
+ * checking if we have an intersection with the boundbox of the volumue
+ * which in most cases corresponds to the boundbox of the object that has
+ * this volume. Also it initializes the rays for the ray marching. */
+ if(!kg->float_volumes[vdb_index]->intersect(ray, NULL)) {
+ return;
+ }
- /* 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;
+ /* t and t1 represent the entry and exit points for each leaf node or tile
+ * containing active voxels. If we don't have any active node in the current
+ * ray path (i.e. empty space) the ray march loop is not executed,
+ * otherwise we loop through all leaves until the end of the volume. */
+ while(kg->float_volumes[vdb_index]->march(&t, &t1)) {
- float3 new_P = ray->P + ray->D * (t + random_jitter_offset);
- VolumeShaderCoefficients coeff;
+ /* Perform small steps through the current leaf or tile. */
+ for(float new_t = step_size * ceilf(t / step_size); new_t <= t1; new_t += step_size, step++) {
+ float dt = new_t - t;
- /* compute segment */
- if(volume_shader_sample(kg, sd, state, new_P, &coeff)) {
- int closure_flag = sd->flag;
- float3 sigma_t = coeff.sigma_a + coeff.sigma_s;
+ /* 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;
- /* compute accumulated transmittance */
- float3 transmittance = volume_color_transmittance(sigma_t, dt);
+ float3 new_P = ray->P + ray->D * (t + random_jitter_offset);
+ VolumeShaderCoefficients coeff;
- /* compute emission attenuated by absorption */
- if(closure_flag & SD_EMISSION) {
- float3 emission = kernel_volume_emission_integrate(&coeff, closure_flag, transmittance, dt);
- accum_emission += accum_transmittance * emission;
- }
+ /* compute segment */
+ if(volume_shader_sample(kg, sd, state, new_P, &coeff)) {
+ int closure_flag = sd->flag;
+ float3 sigma_t = coeff.sigma_a + coeff.sigma_s;
+
+ /* compute accumulated transmittance */
+ float3 transmittance = volume_color_transmittance(sigma_t, dt);
+
+ /* compute emission attenuated by absorption */
+ if(closure_flag & SD_EMISSION) {
+ float3 emission = kernel_volume_emission_integrate(&coeff, closure_flag, transmittance, dt);
+ accum_emission += accum_transmittance * emission;
+ }
- accum_transmittance *= transmittance;
+ accum_transmittance *= transmittance;
- /* compute pdf for distance sampling */
- float3 pdf_distance = dt * accum_transmittance * coeff.sigma_s;
- cdf_distance = cdf_distance + pdf_distance;
+ /* compute pdf for distance sampling */
+ float3 pdf_distance = dt * accum_transmittance * coeff.sigma_s;
+ cdf_distance = cdf_distance + pdf_distance;
+
+ /* write step data */
+ step->sigma_t = sigma_t;
+ step->sigma_s = coeff.sigma_s;
+ step->closure_flag = closure_flag;
+
+ segment->closure_flag |= closure_flag;
+
+ is_last_step_empty = false;
+ segment->numsteps++;
+ }
+ else {
+ if(is_last_step_empty) {
+ /* consecutive empty step, merge */
+ step--;
+ }
+ else {
+ /* store empty step */
+ step->sigma_t = make_float3(0.0f, 0.0f, 0.0f);
+ step->sigma_s = make_float3(0.0f, 0.0f, 0.0f);
+ step->closure_flag = 0;
+
+ segment->numsteps++;
+ is_last_step_empty = true;
+ }
+ }
- /* write step data */
- step->sigma_t = sigma_t;
- step->sigma_s = coeff.sigma_s;
- step->closure_flag = closure_flag;
+ step->accum_transmittance = accum_transmittance;
+ step->cdf_distance = cdf_distance;
+ step->t = new_t;
+ step->shade_t = t + random_jitter_offset;
- segment->closure_flag |= closure_flag;
+ /* stop if at the end of the volume */
+ t = new_t;
+ if(t == ray->t)
+ break;
- is_last_step_empty = false;
- segment->numsteps++;
+ /* stop if nearly all light blocked */
+ if(accum_transmittance.x < tp_eps && accum_transmittance.y < tp_eps && accum_transmittance.z < tp_eps)
+ break;
+ }
}
- else {
- if(is_last_step_empty) {
- /* consecutive empty step, merge */
- step--;
+ }
+ else
+#endif
+ {
+ for(int i = 0; i < max_steps; i++, step++) {
+ /* advance to new position */
+ 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;
+
+ float3 new_P = ray->P + ray->D * (t + random_jitter_offset);
+ VolumeShaderCoefficients coeff;
+
+ /* compute segment */
+ if(volume_shader_sample(kg, sd, state, new_P, &coeff)) {
+ int closure_flag = sd->flag;
+ float3 sigma_t = coeff.sigma_a + coeff.sigma_s;
+
+ /* compute accumulated transmittance */
+ float3 transmittance = volume_color_transmittance(sigma_t, dt);
+
+ /* compute emission attenuated by absorption */
+ if(closure_flag & SD_EMISSION) {
+ float3 emission = kernel_volume_emission_integrate(&coeff, closure_flag, transmittance, dt);
+ accum_emission += accum_transmittance * emission;
+ }
+
+ accum_transmittance *= transmittance;
+
+ /* compute pdf for distance sampling */
+ float3 pdf_distance = dt * accum_transmittance * coeff.sigma_s;
+ cdf_distance = cdf_distance + pdf_distance;
+
+ /* write step data */
+ step->sigma_t = sigma_t;
+ step->sigma_s = coeff.sigma_s;
+ step->closure_flag = closure_flag;
+
+ segment->closure_flag |= closure_flag;
+
+ is_last_step_empty = false;
+ segment->numsteps++;
}
else {
- /* store empty step */
- step->sigma_t = make_float3(0.0f, 0.0f, 0.0f);
- step->sigma_s = make_float3(0.0f, 0.0f, 0.0f);
- step->closure_flag = 0;
+ if(is_last_step_empty) {
+ /* consecutive empty step, merge */
+ step--;
+ }
+ else {
+ /* store empty step */
+ step->sigma_t = make_float3(0.0f, 0.0f, 0.0f);
+ step->sigma_s = make_float3(0.0f, 0.0f, 0.0f);
+ step->closure_flag = 0;
- segment->numsteps++;
- is_last_step_empty = true;
+ segment->numsteps++;
+ is_last_step_empty = true;
+ }
}
- }
- step->accum_transmittance = accum_transmittance;
- step->cdf_distance = cdf_distance;
- step->t = new_t;
- step->shade_t = t + random_jitter_offset;
+ step->accum_transmittance = accum_transmittance;
+ step->cdf_distance = cdf_distance;
+ step->t = new_t;
+ step->shade_t = t + random_jitter_offset;
- /* stop if at the end of the volume */
- t = new_t;
- if(t == ray->t)
- break;
+ /* stop if at the end of the volume */
+ t = new_t;
+ if(t == ray->t)
+ break;
- /* stop if nearly all light blocked */
- if(accum_transmittance.x < tp_eps && accum_transmittance.y < tp_eps && accum_transmittance.z < tp_eps)
- break;
+ /* stop if nearly all light blocked */
+ if(accum_transmittance.x < tp_eps && accum_transmittance.y < tp_eps && accum_transmittance.z < tp_eps)
+ break;
+ }
}
/* store total emission and transmittance */
@@ -847,15 +942,19 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg, PathState *sta
segment->accum_transmittance = accum_transmittance;
/* normalize cumulative density function for distance sampling */
- VolumeStep *last_step = segment->steps + segment->numsteps - 1;
+ int numsteps = segment->numsteps - 1;
+
+ if(numsteps >= 0) {
+ VolumeStep *last_step = segment->steps + segment->numsteps - 1;
- if(!is_zero(last_step->cdf_distance)) {
- VolumeStep *step = &segment->steps[0];
- int numsteps = segment->numsteps;
- float3 inv_cdf_distance_sum = safe_invert_color(last_step->cdf_distance);
+ if(!is_zero(last_step->cdf_distance)) {
+ VolumeStep *step = &segment->steps[0];
+ int numsteps = segment->numsteps;
+ float3 inv_cdf_distance_sum = safe_invert_color(last_step->cdf_distance);
- for(int i = 0; i < numsteps; i++, step++)
- step->cdf_distance *= inv_cdf_distance_sum;
+ for(int i = 0; i < numsteps; i++, step++)
+ step->cdf_distance *= inv_cdf_distance_sum;
+ }
}
}
More information about the Bf-blender-cvs
mailing list