Cycles: Fix some direct lighting leaking into indirect-only bakes

When baking only indirect lighting, light sampling is skipped at the
first bounce. However, light evaluation is still done, so depending
on how the MIS weights end up more or less of the direct lighting
still ends up in the bake.

This is most noticeable with background lighting, but can also be
reproduced with e.g. point lights with a large radius.

Pull Request: https://projects.blender.org/blender/blender/pulls/108955
This commit is contained in:
Lukas Stockner 2023-06-16 03:03:22 +02:00 committed by Lukas Stockner
parent 7169fe65dd
commit a783fe8198
1 changed files with 23 additions and 4 deletions

View File

@ -20,6 +20,16 @@
CCL_NAMESPACE_BEGIN
ccl_device_forceinline bool integrator_intersect_skip_lights(KernelGlobals kg,
IntegratorState state)
{
/* When direct lighting is disabled for baking, we skip light sampling in
* integrate_surface_direct_light for the first bounce. Therefore, in order
* for MIS to be consistent, we also need to skip evaluating lights here. */
return (kernel_data.integrator.filter_closures & FILTER_CLOSURE_DIRECT_LIGHT) &&
(INTEGRATOR_STATE(state, path, bounce) == 1);
}
ccl_device_forceinline bool integrator_intersect_terminate(KernelGlobals kg,
IntegratorState state,
const int shader_flags)
@ -262,7 +272,12 @@ ccl_device_forceinline void integrator_intersect_next_kernel(
}
else {
/* Nothing hit, continue with background kernel. */
integrator_path_next(kg, state, current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
if (integrator_intersect_skip_lights(kg, state)) {
integrator_path_terminate(kg, state, current_kernel);
}
else {
integrator_path_next(kg, state, current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
}
}
}
@ -314,8 +329,12 @@ ccl_device_forceinline void integrator_intersect_next_kernel_after_volume(
}
else {
/* Nothing hit, continue with background kernel. */
integrator_path_next(kg, state, current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
return;
if (integrator_intersect_skip_lights(kg, state)) {
integrator_path_terminate(kg, state, current_kernel);
}
else {
integrator_path_next(kg, state, current_kernel, DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
}
}
}
@ -389,7 +408,7 @@ ccl_device void integrator_intersect_closest(KernelGlobals kg,
#endif /* __MNEE__ */
/* Light intersection for MIS. */
if (kernel_data.integrator.use_light_mis) {
if (kernel_data.integrator.use_light_mis && !integrator_intersect_skip_lights(kg, state)) {
/* NOTE: if we make lights visible to camera rays, we'll need to initialize
* these in the path_state_init. */
const int last_type = INTEGRATOR_STATE(state, isect, type);