Cycles: record path guiding information for dedicated shadow ray #108195

Merged
Brecht Van Lommel merged 1 commits from brecht/blender:cycles-light-linking into cycles-light-linking 2023-05-23 16:48:35 +02:00
5 changed files with 45 additions and 10 deletions

View File

@ -399,9 +399,8 @@ ccl_device_forceinline void guiding_record_background(KernelGlobals kg,
#endif
}
/* Records the scattered contribution of a next event estimation
* (i.e., a direct light estimate scattered at the current path vertex
* towards the previous vertex). */
/* Records direct lighting from either next event estimation or a dedicated BSDF
* sampled shadow ray. */
ccl_device_forceinline void guiding_record_direct_light(KernelGlobals kg,
IntegratorShadowState state)
{
@ -414,7 +413,22 @@ ccl_device_forceinline void guiding_record_direct_light(KernelGlobals kg,
INTEGRATOR_STATE(state, shadow_path, unlit_throughput));
const float3 Lo_rgb = spectrum_to_rgb(Lo);
openpgl::cpp::AddScatteredContribution(state->shadow_path.path_segment, guiding_vec3f(Lo_rgb));
const float mis_weight = INTEGRATOR_STATE(state, shadow_path, guiding_mis_weight);
if (mis_weight == 0.0f) {
/* Scattered contribution of a next event estimation (i.e., a direct light estimate
* scattered at the current path vertex towards the previous vertex). */
openpgl::cpp::AddScatteredContribution(state->shadow_path.path_segment,
guiding_vec3f(Lo_rgb));
}
else {
/* Dedicated shadow ray for BSDF sampled ray direction.
* The mis weight was already folded into the throughput, so need to divide it out. */
openpgl::cpp::SetDirectContribution(state->shadow_path.path_segment,
guiding_vec3f(Lo_rgb / mis_weight));
openpgl::cpp::SetMiWeight(state->shadow_path.path_segment, mis_weight);
}
}
#endif
}

View File

@ -81,6 +81,7 @@ ccl_device bool shadow_linking_shade_light(KernelGlobals kg,
ccl_private Intersection &ccl_restrict isect,
ccl_private ShaderData *emission_sd,
ccl_private Spectrum &ccl_restrict bsdf_spectrum,
ccl_private float &mis_weight,
ccl_private int &ccl_restrict light_group)
{
LightSample ls ccl_optional_struct_init;
@ -101,7 +102,6 @@ ccl_device bool shadow_linking_shade_light(KernelGlobals kg,
}
/* MIS weighting. */
float mis_weight = 1.0f;
if (!(path_flag & PATH_RAY_MIS_SKIP)) {
mis_weight = shadow_linking_light_sample_mis_weight(kg, state, path_flag, &ls, ray.P);
}
@ -124,6 +124,7 @@ ccl_device bool shadow_linking_shade_surface_emission(KernelGlobals kg,
ccl_global float *ccl_restrict render_buffer,
ccl_private Spectrum &ccl_restrict
bsdf_spectrum,
ccl_private float &mis_weight,
ccl_private int &ccl_restrict light_group)
{
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
@ -145,7 +146,6 @@ ccl_device bool shadow_linking_shade_surface_emission(KernelGlobals kg,
}
const Spectrum L = surface_shader_emission(emission_sd);
float mis_weight = 1.0f;
const bool has_mis = !(path_flag & PATH_RAY_MIS_SKIP) &&
(emission_sd->flag &
@ -182,22 +182,35 @@ ccl_device void shadow_linking_shade(KernelGlobals kg,
ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
Spectrum bsdf_spectrum;
float mis_weight = 1.0f;
int light_group = LIGHTGROUP_NONE;
if (isect.type == PRIMITIVE_LAMP) {
if (!shadow_linking_shade_light(
kg, state, ray, isect, emission_sd, bsdf_spectrum, light_group)) {
kg, state, ray, isect, emission_sd, bsdf_spectrum, mis_weight, light_group))
{
return;
}
}
else {
if (!shadow_linking_shade_surface_emission(
kg, state, ray, isect, emission_sd, render_buffer, bsdf_spectrum, light_group))
if (!shadow_linking_shade_surface_emission(kg,
state,
ray,
isect,
emission_sd,
render_buffer,
bsdf_spectrum,
mis_weight,
light_group))
{
return;
}
}
if (is_zero(bsdf_spectrum)) {
return;
}
shadow_linking_setup_ray_from_intersection(state, &ray, &isect);
/* Branch off shadow kernel. */
@ -226,7 +239,12 @@ ccl_device void shadow_linking_shade(KernelGlobals kg,
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, flag) = shadow_flag;
// TODO: Disable path guiding for this shadow ray?
# ifdef __PATH_GUIDING__
if (kernel_data.integrator.train_guiding) {
guiding_record_light_surface_segment(kg, state, &isect);
INTEGRATOR_STATE(shadow_state, shadow_path, guiding_mis_weight) = mis_weight;
}
# endif
}
#endif /* __SHADOW_LINKING__ */

View File

@ -226,6 +226,7 @@ integrate_direct_light_shadow_init_common(KernelGlobals kg,
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unlit_throughput) = unlit_throughput;
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = INTEGRATOR_STATE(
state, guiding, path_segment);
INTEGRATOR_STATE(shadow_state, shadow_path, guiding_mis_weight) = 0.0f;
brecht marked this conversation as resolved
Review

INTEGRATOR_STATE_WRITE

`INTEGRATOR_STATE_WRITE`
#endif
return shadow_state;

View File

@ -893,6 +893,7 @@ ccl_device_forceinline void integrate_volume_direct_light(
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unlit_throughput) = unlit_throughput;
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = INTEGRATOR_STATE(
state, guiding, path_segment);
INTEGRATOR_STATE(shadow_state, shadow_path, guiding_mis_weight) = 0.0f;
brecht marked this conversation as resolved
Review

INTEGRATOR_STATE_WRITE

`INTEGRATOR_STATE_WRITE`
# endif
integrator_state_copy_volume_stack_to_shadow(kg, shadow_state, state);

View File

@ -50,6 +50,7 @@ KERNEL_STRUCT_MEMBER(shadow_path,
#else
KERNEL_STRUCT_MEMBER(shadow_path, uint64_t, path_segment, KERNEL_FEATURE_PATH_GUIDING)
#endif
KERNEL_STRUCT_MEMBER(shadow_path, float, guiding_mis_weight, KERNEL_FEATURE_PATH_GUIDING)
KERNEL_STRUCT_END(shadow_path)
/********************************** Shadow Ray *******************************/