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
This commit is contained in:
Weizhen Huang
2024-08-19 15:52:35 +02:00
committed by Weizhen Huang
parent a6ce1cd9c7
commit be0d2e19b5
3 changed files with 12 additions and 1 deletions

View File

@@ -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)) {

View File

@@ -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 */