[Bf-blender-cvs] [19651417f9b] cycles-x: Cycles X: sample position on light before stepping through volume
Brecht Van Lommel
noreply at git.blender.org
Fri Jul 23 19:29:02 CEST 2021
Commit: 19651417f9b5deb5c06cfd6ecec5e906e9e02175
Author: Brecht Van Lommel
Date: Wed Jul 7 21:01:54 2021 +0200
Branches: cycles-x
https://developer.blender.org/rB19651417f9b5deb5c06cfd6ecec5e906e9e02175
Cycles X: sample position on light before stepping through volume
In preparation of equiangular sampling.
Ref D11845
===================================================================
M intern/cycles/kernel/integrator/integrator_shade_volume.h
===================================================================
diff --git a/intern/cycles/kernel/integrator/integrator_shade_volume.h b/intern/cycles/kernel/integrator/integrator_shade_volume.h
index 344f6cb3167..08457473cd8 100644
--- a/intern/cycles/kernel/integrator/integrator_shade_volume.h
+++ b/intern/cycles/kernel/integrator/integrator_shade_volume.h
@@ -519,35 +519,56 @@ volume_integrate_heterogeneous(INTEGRATOR_STATE_ARGS,
# ifdef __EMISSION__
/* Path tracing: sample point on light and evaluate light shader, then
* queue shadow ray to be traced. */
-ccl_device_forceinline void integrate_volume_direct_light(INTEGRATOR_STATE_ARGS,
- ShaderData *sd,
- const ShaderVolumePhases *phases,
- const RNGState *rng_state)
+ccl_device_forceinline bool integrate_volume_sample_light(INTEGRATOR_STATE_ARGS,
+ const ShaderData *ccl_restrict sd,
+ const RNGState *ccl_restrict rng_state,
+ LightSample *ccl_restrict ls)
{
/* Test if there is a light or BSDF that needs direct light. */
if (!kernel_data.integrator.use_direct_light) {
- return;
+ return false;
}
/* Sample position on a light. */
- LightSample ls ccl_optional_struct_init;
+ const int path_flag = INTEGRATOR_STATE(path, flag);
+ const uint bounce = INTEGRATOR_STATE(path, bounce);
+ float light_u, light_v;
+ path_state_rng_2D(kg, rng_state, PRNG_LIGHT_U, &light_u, &light_v);
+
+ light_sample(kg, light_u, light_v, sd->time, sd->P, bounce, path_flag, ls);
+
+ if (ls->shader & SHADER_EXCLUDE_SCATTER) {
+ return false;
+ }
+
+ return true;
+}
+
+/* Path tracing: sample point on light and evaluate light shader, then
+ * queue shadow ray to be traced. */
+ccl_device_forceinline void integrate_volume_direct_light(INTEGRATOR_STATE_ARGS,
+ const ShaderData *ccl_restrict sd,
+ const ShaderVolumePhases *ccl_restrict
+ phases,
+ const RNGState *ccl_restrict rng_state,
+ LightSample *ccl_restrict ls)
+{
+ /* Sample position on the same light again, now from the shading
+ * point where we scattered.
+ *
+ * TODO: decorrelate random numbers and use light_sample_new_position to
+ * avoid resampling the CDF. */
{
const int path_flag = INTEGRATOR_STATE(path, flag);
const uint bounce = INTEGRATOR_STATE(path, bounce);
float light_u, light_v;
path_state_rng_2D(kg, rng_state, PRNG_LIGHT_U, &light_u, &light_v);
- if (!light_sample(kg, light_u, light_v, sd->time, sd->P, bounce, path_flag, &ls)) {
+ if (!light_sample(kg, light_u, light_v, sd->time, sd->P, bounce, path_flag, ls)) {
return;
}
}
- if (ls.shader & SHADER_EXCLUDE_SCATTER) {
- return;
- }
-
- kernel_assert(ls.pdf != 0.0f);
-
/* Evaluate light shader.
*
* TODO: can we reuse sd memory? In theory we can move this after
@@ -557,32 +578,32 @@ ccl_device_forceinline void integrate_volume_direct_light(INTEGRATOR_STATE_ARGS,
ShaderDataTinyStorage emission_sd_storage;
ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
const float3 light_eval = light_sample_shader_eval(
- INTEGRATOR_STATE_PASS, emission_sd, &ls, sd->time);
+ INTEGRATOR_STATE_PASS, emission_sd, ls, sd->time);
if (is_zero(light_eval)) {
return;
}
/* Evaluate BSDF. */
BsdfEval phase_eval ccl_optional_struct_init;
- const float phase_pdf = shader_volume_phase_eval(kg, sd, phases, ls.D, &phase_eval);
+ const float phase_pdf = shader_volume_phase_eval(kg, sd, phases, ls->D, &phase_eval);
- if (ls.shader & SHADER_USE_MIS) {
- float mis_weight = power_heuristic(ls.pdf, phase_pdf);
+ if (ls->shader & SHADER_USE_MIS) {
+ float mis_weight = power_heuristic(ls->pdf, phase_pdf);
bsdf_eval_mul(&phase_eval, mis_weight);
}
- bsdf_eval_mul3(&phase_eval, light_eval / ls.pdf);
+ bsdf_eval_mul3(&phase_eval, light_eval / ls->pdf);
/* Path termination. */
const float terminate = path_state_rng_light_termination(kg, rng_state);
- if (light_sample_terminate(kg, &ls, &phase_eval, terminate)) {
+ if (light_sample_terminate(kg, ls, &phase_eval, terminate)) {
return;
}
/* Create shadow ray. */
Ray ray ccl_optional_struct_init;
- light_sample_to_volume_shadow_ray(kg, sd, &ls, sd->P, &ray);
- const bool is_light = light_sample_is_light(&ls);
+ light_sample_to_volume_shadow_ray(kg, sd, ls, sd->P, &ray);
+ const bool is_light = light_sample_is_light(ls);
/* Write shadow ray and associated state to global memory. */
integrator_state_write_shadow_ray(INTEGRATOR_STATE_PASS, &ray);
@@ -687,12 +708,20 @@ ccl_device VolumeIntegrateEvent volume_integrate(INTEGRATOR_STATE_ARGS,
ShaderData sd;
shader_setup_from_volume(kg, &sd, ray);
- float3 throughput = INTEGRATOR_STATE(path, throughput);
-
/* Load random number state. */
RNGState rng_state;
path_state_rng_load(INTEGRATOR_STATE_PASS, &rng_state);
+ /* Sample light ahead of volume stepping. */
+ LightSample ls ccl_optional_struct_init;
+ const bool need_light_sample = !(INTEGRATOR_STATE(path, flag) & PATH_RAY_TERMINATE);
+ if (need_light_sample) {
+ integrate_volume_sample_light(INTEGRATOR_STATE_PASS, &sd, &rng_state, &ls);
+ }
+
+ /* Step through volume. */
+ float3 throughput = INTEGRATOR_STATE(path, throughput);
+
const float step_size = volume_stack_step_size(INTEGRATOR_STATE_PASS, [=](const int i) {
return integrator_state_read_volume_stack(INTEGRATOR_STATE_PASS, i);
});
@@ -724,7 +753,7 @@ ccl_device VolumeIntegrateEvent volume_integrate(INTEGRATOR_STATE_ARGS,
if (event == VOLUME_PATH_SCATTERED) {
/* Direct light. */
- integrate_volume_direct_light(INTEGRATOR_STATE_PASS, &sd, &phases, &rng_state);
+ integrate_volume_direct_light(INTEGRATOR_STATE_PASS, &sd, &phases, &rng_state, &ls);
/* Scatter. */
if (!integrate_volume_phase_scatter(INTEGRATOR_STATE_PASS, &sd, &phases, &rng_state)) {
More information about the Bf-blender-cvs
mailing list