Fix #136319: Incorrect transparent bounce count with spatial splits

The transparent bounce test was too optimistic in regards to the intersection
being considered. The check needs to happen after it has been validated that
it is not duplicate.

It was already the case for Metal and HIP-RT, but not for Embree and BVH2.

Tests updated by: Alaska <Alaskayou01@gmail.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/136325
This commit is contained in:
Sergey Sharybin
2025-03-22 04:51:42 +01:00
committed by Alaska
parent 8c35fe05b6
commit 5ce4e91a80
3 changed files with 14 additions and 9 deletions

View File

@@ -222,14 +222,12 @@ ccl_device_inline
/* shadow ray early termination */
if (hit) {
/* detect if this surface has a shader with transparent shadows */
/* todo: optimize so primitive visibility flag indicates if
* the primitive has a transparent shadow shader? */
/* Detect if this surface has a shader with transparent shadows. */
/* TODO: optimize so primitive visibility flag indicates if the primitive has a
* transparent shadow shader? */
const int flags = intersection_get_shader_flags(kg, isect.prim, isect.type);
if (!(flags & SD_HAS_TRANSPARENT_SHADOW) || num_hits >= max_hits) {
/* If no transparent shadows, all light is blocked and we can
* stop immediately. */
if ((flags & SD_HAS_TRANSPARENT_SHADOW) == 0) {
/* If no transparent shadows, all light is blocked and we can stop immediately. */
return true;
}
@@ -244,6 +242,9 @@ ccl_device_inline
}
num_hits++;
if (num_hits > max_hits) {
return true;
}
bool record_intersection = true;

View File

@@ -345,7 +345,7 @@ ccl_device_forceinline void kernel_embree_filter_occluded_shadow_all_func_impl(
/* If no transparent shadows or max number of hits exceeded, all light is blocked. */
const int flags = intersection_get_shader_flags(kg, current_isect.prim, current_isect.type);
if (!(flags & (SD_HAS_TRANSPARENT_SHADOW)) || ctx->num_hits >= ctx->max_hits) {
if ((flags & SD_HAS_TRANSPARENT_SHADOW) == 0) {
ctx->opaque_hit = true;
return;
}
@@ -358,6 +358,10 @@ ccl_device_forceinline void kernel_embree_filter_occluded_shadow_all_func_impl(
}
++ctx->num_hits;
if (ctx->num_hits > ctx->max_hits) {
ctx->opaque_hit = true;
return;
}
/* Always use baked shadow transparency for curves. */
if (current_isect.type & PRIMITIVE_CURVE) {