From 4e15fc22567f6b185f056f553d8fd9fbcaa8f8d1 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 23 May 2023 16:12:06 +0200 Subject: [PATCH] Cycles: record path guiding information for dedicated shadow ray --- intern/cycles/kernel/integrator/guiding.h | 22 +++++++++++--- .../kernel/integrator/shade_dedicated_light.h | 30 +++++++++++++++---- .../cycles/kernel/integrator/shade_surface.h | 1 + .../cycles/kernel/integrator/shade_volume.h | 1 + .../kernel/integrator/shadow_state_template.h | 1 + 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/intern/cycles/kernel/integrator/guiding.h b/intern/cycles/kernel/integrator/guiding.h index ca005f359de..1abcfb1f6ad 100644 --- a/intern/cycles/kernel/integrator/guiding.h +++ b/intern/cycles/kernel/integrator/guiding.h @@ -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 } diff --git a/intern/cycles/kernel/integrator/shade_dedicated_light.h b/intern/cycles/kernel/integrator/shade_dedicated_light.h index 4b3e66cee7a..56ec7dcd162 100644 --- a/intern/cycles/kernel/integrator/shade_dedicated_light.h +++ b/intern/cycles/kernel/integrator/shade_dedicated_light.h @@ -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__ */ diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 2b5c9f00bbc..e80dfee44e9 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -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; #endif return shadow_state; diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h index 12a06c2d9e3..2ea6f44ab6d 100644 --- a/intern/cycles/kernel/integrator/shade_volume.h +++ b/intern/cycles/kernel/integrator/shade_volume.h @@ -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; # endif integrator_state_copy_volume_stack_to_shadow(kg, shadow_state, state); diff --git a/intern/cycles/kernel/integrator/shadow_state_template.h b/intern/cycles/kernel/integrator/shadow_state_template.h index bb1ab88d7e2..936ffb32d72 100644 --- a/intern/cycles/kernel/integrator/shadow_state_template.h +++ b/intern/cycles/kernel/integrator/shadow_state_template.h @@ -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 *******************************/ -- 2.30.2