From be0d2e19b54f122571847eae2f3fbc3324ea9dfd Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Mon, 19 Aug 2024 15:52:35 +0200 Subject: [PATCH] Fix #115998: Cycles volume too dark when shadow ray visibility is off when tracing shadow ray through a volume and no hit is registered, we consider the whole ray segment inside the volume. However, no hit registered could also happen when the volume is invisible to shadow ray. We should explicitly check this case and skip rendering the volume segment instead. Pull Request: https://projects.blender.org/blender/blender/pulls/126139 --- intern/cycles/kernel/integrator/shade_shadow.h | 1 + intern/cycles/kernel/integrator/volume_shader.h | 10 ++++++++++ tests/data | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) 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