diff --git a/intern/cycles/kernel/integrator/shade_shadow.h b/intern/cycles/kernel/integrator/shade_shadow.h index 24a0667bcbe..d395e76c041 100644 --- a/intern/cycles/kernel/integrator/shade_shadow.h +++ b/intern/cycles/kernel/integrator/shade_shadow.h @@ -104,6 +104,7 @@ ccl_device_inline bool integrate_transparent_shadow(KernelGlobals kg, /* Accumulate shadow for transparent surfaces. */ const uint num_recorded_hits = min(num_hits, INTEGRATOR_SHADOW_ISECT_SIZE); + /* Plus one to account for world volume, which has no boundary to hit but casts shadows. */ for (uint hit = 0; hit < num_recorded_hits + 1; hit++) { /* Volume shaders. */ if (hit < num_recorded_hits || !shadow_intersections_has_remaining(num_hits)) { diff --git a/intern/cycles/kernel/integrator/volume_shader.h b/intern/cycles/kernel/integrator/volume_shader.h index 595353f9236..9f86e74aedb 100644 --- a/intern/cycles/kernel/integrator/volume_shader.h +++ b/intern/cycles/kernel/integrator/volume_shader.h @@ -482,6 +482,16 @@ ccl_device_inline void volume_shader_eval(KernelGlobals kg, if (sd->object != OBJECT_NONE) { sd->object_flag |= kernel_data_fetch(object_flag, sd->object); + if (shadow && !(kernel_data_fetch(objects, sd->object).visibility & + (path_flag & PATH_RAY_ALL_VISIBILITY))) + { + /* If volume is invisible to shadow ray, the hit is not registered, but the volume is still + * in the stack. Skip the volume in such cases. */ + /* NOTE: `SHADOW_CATCHER_PATH_VISIBILITY()` is omitted because `path_flag` is just + * `PATH_RAY_SHADOW` when evaluating shadows. */ + continue; + } + # ifdef __OBJECT_MOTION__ /* todo: this is inefficient for motion blur, we should be * caching matrices instead of recomputing them each step */ diff --git a/tests/data b/tests/data index 1a0c77d8458..528aadad4bd 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit 1a0c77d8458eaf54d75b51fa5c0b752f7a648a39 +Subproject commit 528aadad4bdbc43b858a1bbc3585ed7c84797106