[Bf-blender-cvs] [59979c3d8fb] cycles_path_guiding: Simplify volume guiding and add TODO comments about seemingly wrong code
Brecht Van Lommel
noreply at git.blender.org
Tue Sep 20 21:00:37 CEST 2022
Commit: 59979c3d8fbe517ecacc021e2be53c08887ea75a
Author: Brecht Van Lommel
Date: Tue Sep 20 19:41:45 2022 +0200
Branches: cycles_path_guiding
https://developer.blender.org/rB59979c3d8fbe517ecacc021e2be53c08887ea75a
Simplify volume guiding and add TODO comments about seemingly wrong code
===================================================================
M intern/cycles/kernel/integrator/shade_volume.h
M intern/cycles/kernel/integrator/volume_shader.h
===================================================================
diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h
index 9d237d697a3..d10b53516e1 100644
--- a/intern/cycles/kernel/integrator/shade_volume.h
+++ b/intern/cycles/kernel/integrator/shade_volume.h
@@ -873,12 +873,7 @@ ccl_device_forceinline bool integrate_volume_phase_scatter(
float2 rand_phase = path_state_rng_2D(kg, rng_state, PRNG_VOLUME_PHASE);
-# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
ccl_private const ShaderVolumeClosure *svc = volume_shader_phase_pick(phases, &rand_phase);
- if (!svc) {
- return false;
- }
-# endif
/* Phase closure, sample direction. */
float phase_pdf = 0.0f, unguided_phase_pdf = 0.0f;
@@ -909,8 +904,15 @@ ccl_device_forceinline bool integrate_volume_phase_scatter(
else
# endif
{
- label = volume_shader_phase_sample(
- kg, sd, phases, rand_phase, &phase_eval, &phase_omega_in, &phase_pdf, &sampled_roughness);
+ label = volume_shader_phase_sample(kg,
+ sd,
+ phases,
+ svc,
+ rand_phase,
+ &phase_eval,
+ &phase_omega_in,
+ &phase_pdf,
+ &sampled_roughness);
if (phase_pdf == 0.0f || bsdf_eval_is_zero(&phase_eval)) {
return false;
@@ -990,8 +992,7 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
const float step_size = volume_stack_step_size(kg, volume_read_lambda_pass);
# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
- const bool use_guiding = kernel_data.integrator.use_guiding;
- const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
+ const float3 initial_throughput = INTEGRATOR_STATE(state, path, throughput);
# endif
/* TODO: expensive to zero closures? */
@@ -1019,31 +1020,35 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
return VOLUME_PATH_MISSED;
}
- bool guiding_generated_new_segment = false;
# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
- if (use_guiding) {
+ bool guiding_generated_new_segment = false;
+ if (kernel_data.integrator.use_guiding) {
+ /* Record transmittance using change in throughput. */
float3 transmittance_weight = spectrum_to_rgb(
- safe_divide_color(result.indirect_throughput, throughput));
+ safe_divide_color(result.indirect_throughput, initial_throughput));
guiding_record_volume_transmission(kg, state, transmittance_weight);
- if ((result.direct_scatter && result.indirect_scatter) &&
- (result.direct_t == result.indirect_t)) {
- // next segment
- const float3 P = ray->P + result.indirect_t * ray->D;
- guiding_record_volume_segment(kg, state, P, sd.I);
- guiding_generated_new_segment = true;
- }
-# if PATH_GUIDING_LEVEL >= 4
if (result.indirect_scatter) {
const float3 P = ray->P + result.indirect_t * ray->D;
+
+ /* Record volume segment up to direct scatter position.
+ * TODO: volume segment is wrong when direct_t and indirect_t. */
+ if (result.direct_scatter && (result.direct_t == result.indirect_t)) {
+ guiding_record_volume_segment(kg, state, P, sd.I);
+ guiding_generated_new_segment = true;
+ }
+
+# if PATH_GUIDING_LEVEL >= 4
+ /* TODO: this position will be wrong for direct light pdf computation,
+ * since the direct light position may be different? */
volume_shader_prepare_guiding(
kg, state, &sd, &rng_state, P, ray->D, &result.direct_phases, direct_sample_method);
+# endif
}
else {
- state->guiding.volume_guiding_sampling_prob = 0.f;
+ /* No guiding if we don't scatter. */
state->guiding.use_volume_guiding = false;
}
-# endif
}
# endif
@@ -1063,7 +1068,7 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
/* Indirect light.
*
- * Only divide throughput by survival_probability if we scatter. For the attenuation
+ * Only divide throughput by continuation_probability if we scatter. For the attenuation
* case the next surface will already do this division. */
if (result.indirect_scatter) {
result.indirect_throughput /= continuation_probability;
@@ -1073,9 +1078,12 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
if (result.indirect_scatter) {
sd.P = ray->P + result.indirect_t * ray->D;
+# if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
if (!guiding_generated_new_segment) {
guiding_record_volume_segment(kg, state, sd.P, sd.I);
}
+# endif
+
if (integrate_volume_phase_scatter(kg, state, &sd, &rng_state, &result.indirect_phases)) {
return VOLUME_PATH_SCATTERED;
}
@@ -1127,7 +1135,7 @@ ccl_device void integrator_shade_volume(KernelGlobals kg,
integrator_path_terminate(kg, state, DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME);
return;
}
- else { // VOLUME_PATH_ATTENUATED
+ else {
/* Continue to background, light or surface. */
integrator_intersect_next_kernel_after_volume<DEVICE_KERNEL_INTEGRATOR_SHADE_VOLUME>(
kg, state, &isect, render_buffer);
diff --git a/intern/cycles/kernel/integrator/volume_shader.h b/intern/cycles/kernel/integrator/volume_shader.h
index 2056f8ab7c1..b09f61ac563 100644
--- a/intern/cycles/kernel/integrator/volume_shader.h
+++ b/intern/cycles/kernel/integrator/volume_shader.h
@@ -164,7 +164,6 @@ ccl_device_inline void volume_shader_prepare_guiding(KernelGlobals kg,
/* Phase Evaluation & Sampling */
-# if defined(__PATH_GUIDING__)
/* Randomly sample a volume phase function proportional to ShaderClosure.sample_weight. */
ccl_device_inline ccl_private const ShaderVolumeClosure *volume_shader_phase_pick(
ccl_private const ShaderVolumePhases *phases, ccl_private float2 *rand_phase)
@@ -175,7 +174,7 @@ ccl_device_inline ccl_private const ShaderVolumeClosure *volume_shader_phase_pic
/* pick a phase closure based on sample weights */
float sum = 0.0f;
- for (sampled = 0; sampled < phases->num_closure; sampled++) {
+ for (int i = 0; i < phases->num_closure; i++) {
ccl_private const ShaderVolumeClosure *svc = &phases->closure[sampled];
sum += svc->sample_weight;
}
@@ -183,29 +182,25 @@ ccl_device_inline ccl_private const ShaderVolumeClosure *volume_shader_phase_pic
float r = (*rand_phase).x * sum;
float partial_sum = 0.0f;
- for (sampled = 0; sampled < phases->num_closure; sampled++) {
- ccl_private const ShaderVolumeClosure *svc = &phases->closure[sampled];
+ for (int i = 0; i < phases->num_closure; i++) {
+ ccl_private const ShaderVolumeClosure *svc = &phases->closure[i];
float next_sum = partial_sum + svc->sample_weight;
if (r <= next_sum) {
/* Rescale to reuse for volume phase direction sample. */
+ sampled = i;
(*rand_phase).x = (r - partial_sum) / svc->sample_weight;
break;
}
partial_sum = next_sum;
}
-
- if (sampled == phases->num_closure) {
- return NULL;
- }
}
/* todo: this isn't quite correct, we don't weight anisotropy properly
* depending on color channels, even if this is perhaps not a common case */
return &phases->closure[sampled];
}
-# endif
ccl_device_inline float _volume_shader_phase_eval_mis(ccl_private const ShaderData *sd,
ccl_private const ShaderVolumePhases *phases,
@@ -353,54 +348,18 @@ ccl_device int volume_shader_phase_guided_sample(KernelGlobals kg,
ccl_device int volume_shader_phase_sample(KernelGlobals kg,
ccl_private const ShaderData *sd,
ccl_private const ShaderVolumePhases *phases,
+ ccl_private const ShaderVolumeClosure *svc,
float2 rand_phase,
ccl_private BsdfEval *phase_eval,
ccl_private float3 *omega_in,
ccl_private float *pdf,
ccl_private float *sampled_roughness)
{
- int sampled = 0;
-
- if (phases->num_closure > 1) {
- /* pick a phase closure based on sample weights */
- float sum = 0.0f;
-
- for (sampled = 0; sampled < phases->num_closure; sampled++) {
- ccl_private const ShaderVolumeClosure *svc = &phases->closure[sampled];
- sum += svc->sample_weight;
- }
-
- float r = rand_phase.x * sum;
- float partial_sum = 0.0f;
-
- for (sampled = 0; sampled < phases->num_closure; sampled++) {
- ccl_private const ShaderVolumeClosure *svc = &phases->closure[sampled];
- float next_sum = partial_sum + svc->sample_weight;
-
- if (r <= next_sum) {
- /* Rescale to reuse for BSDF direction sample. */
- rand_phase.x = (r - partial_sum) / svc->sample_weight;
- break;
- }
-
- partial_sum = next_sum;
- }
-
- if (sampled == phases->num_closure) {
- *pdf = 0.0f;
- return LABEL_NONE;
- }
- }
-
- /* todo: this isn't quite correct, we don't weight anisotropy properly
- * depending on color channels, even if this is perhaps not a common case */
- ccl_private const ShaderVolumeClosure *svc = &phases->closure[sampled];
- int label;
*sampled_roughness = 1.0f - fabsf(svc->g);
Spectrum eval = zero_spectrum();
*pdf = 0.0f;
- label = volume_phase_sample(sd, svc, rand_phase.x, rand_phase.y, &eval, omega_in, pdf);
+ int label = volume_phase_sample(sd, svc, rand_phase.x, rand_phase.y, &eval, omega_in, pdf);
if (*pdf != 0.0f) {
bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval);
@@ -409,26 +368,6 @@ ccl_device int volume_shader_phase_sample(KernelGlobals kg,
return label;
}
-ccl_device int volume_shader_phase_sample_closure(KernelGlobals kg,
- ccl_private
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list