diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2017-08-02 00:40:38 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2017-08-07 18:44:15 +0300 |
commit | 8b73c9a437ffe5b5d44bd670a4129b5850d15b04 (patch) | |
tree | 536b22c6548737849939c76a8693fc4829476764 /intern | |
parent | dc213ca06627babe09246412f13bce090c57779f (diff) |
Fix Cycles shadow catcher objects influencing each other.
Since all the shadow catchers are already assumed to be in the footage,
the shadows they cast on each other are already in the footage too. So
don't just let shadow catchers skip self, but all shadow catchers.
Another justification is that it should not matter if the shadow catcher
is modeled as one object or multiple separate objects, the resulting
render should be the same.
Differential Revision: https://developer.blender.org/D2763
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/bvh/bvh.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh2.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh4.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/bvh/bvh.h | 12 | ||||
-rw-r--r-- | intern/cycles/kernel/bvh/bvh_shadow_all.h | 31 | ||||
-rw-r--r-- | intern/cycles/kernel/bvh/bvh_traversal.h | 12 | ||||
-rw-r--r-- | intern/cycles/kernel/bvh/qbvh_shadow_all.h | 25 | ||||
-rw-r--r-- | intern/cycles/kernel/bvh/qbvh_traversal.h | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 3 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path_branched.h | 3 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path_state.h | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_shadow.h | 84 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 37 | ||||
-rw-r--r-- | intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h | 1 | ||||
-rw-r--r-- | intern/cycles/render/osl.cpp | 6 |
15 files changed, 99 insertions, 137 deletions
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index 33143e2d8aa..c7e11539cf9 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -167,6 +167,10 @@ void BVH::pack_primitives() if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE) pack.prim_visibility[i] |= PATH_RAY_CURVE; + if (ob->is_shadow_catcher) + pack.prim_visibility[i] &= ~PATH_RAY_SHADOW_NON_CATCHER; + else + pack.prim_visibility[i] &= ~PATH_RAY_SHADOW_CATCHER; } else { pack.prim_tri_index[i] = -1; diff --git a/intern/cycles/bvh/bvh2.cpp b/intern/cycles/bvh/bvh2.cpp index 340ba7dcf53..3e3a5d604d8 100644 --- a/intern/cycles/bvh/bvh2.cpp +++ b/intern/cycles/bvh/bvh2.cpp @@ -314,6 +314,10 @@ void BVH2::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility) } visibility |= ob->visibility; + if (ob->is_shadow_catcher) + visibility &= ~PATH_RAY_SHADOW_NON_CATCHER; + else + visibility &= ~PATH_RAY_SHADOW_CATCHER; } /* TODO(sergey): De-duplicate with pack_leaf(). */ diff --git a/intern/cycles/bvh/bvh4.cpp b/intern/cycles/bvh/bvh4.cpp index 5034ab811d5..0e460db7ed7 100644 --- a/intern/cycles/bvh/bvh4.cpp +++ b/intern/cycles/bvh/bvh4.cpp @@ -440,6 +440,10 @@ void BVH4::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility) } visibility |= ob->visibility; + if (ob->is_shadow_catcher) + visibility &= ~PATH_RAY_SHADOW_NON_CATCHER; + else + visibility &= ~PATH_RAY_SHADOW_CATCHER; } /* TODO(sergey): This is actually a copy of pack_leaf(), diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h index 85741016b25..cf0c8542d69 100644 --- a/intern/cycles/kernel/bvh/bvh.h +++ b/intern/cycles/kernel/bvh/bvh.h @@ -233,7 +233,7 @@ ccl_device_intersect void scene_intersect_subsurface(KernelGlobals *kg, ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg, const Ray *ray, Intersection *isect, - int skip_object, + uint visibility, uint max_hits, uint *num_hits) { @@ -244,7 +244,7 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg, return bvh_intersect_shadow_all_hair_motion(kg, ray, isect, - skip_object, + visibility, max_hits, num_hits); } @@ -253,7 +253,7 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg, return bvh_intersect_shadow_all_motion(kg, ray, isect, - skip_object, + visibility, max_hits, num_hits); } @@ -264,7 +264,7 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg, return bvh_intersect_shadow_all_hair(kg, ray, isect, - skip_object, + visibility, max_hits, num_hits); } @@ -275,7 +275,7 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg, return bvh_intersect_shadow_all_instancing(kg, ray, isect, - skip_object, + visibility, max_hits, num_hits); } @@ -284,7 +284,7 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg, return bvh_intersect_shadow_all(kg, ray, isect, - skip_object, + visibility, max_hits, num_hits); } diff --git a/intern/cycles/kernel/bvh/bvh_shadow_all.h b/intern/cycles/kernel/bvh/bvh_shadow_all.h index 267e098f912..72188e3a845 100644 --- a/intern/cycles/kernel/bvh/bvh_shadow_all.h +++ b/intern/cycles/kernel/bvh/bvh_shadow_all.h @@ -45,7 +45,7 @@ ccl_device_inline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, const Ray *ray, Intersection *isect_array, - const int skip_object, + const uint visibility, const uint max_hits, uint *num_hits) { @@ -119,7 +119,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, idir, isect_t, node_addr, - PATH_RAY_SHADOW, + visibility, dist); #else // __KERNEL_SSE2__ traverse_mask = NODE_INTERSECT(kg, @@ -134,7 +134,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, idirsplat, shufflexyz, node_addr, - PATH_RAY_SHADOW, + visibility, dist); #endif // __KERNEL_SSE2__ @@ -186,17 +186,6 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, /* primitive intersection */ while(prim_addr < prim_addr2) { kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) == p_type); - -#ifdef __SHADOW_TRICKS__ - uint tri_object = (object == OBJECT_NONE) - ? kernel_tex_fetch(__prim_object, prim_addr) - : object; - if(tri_object == skip_object) { - ++prim_addr; - continue; - } -#endif - bool hit; /* todo: specialized intersect functions which don't fill in @@ -209,7 +198,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, isect_array, P, dir, - PATH_RAY_SHADOW, + visibility, object, prim_addr); break; @@ -221,7 +210,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, P, dir, ray->time, - PATH_RAY_SHADOW, + visibility, object, prim_addr); break; @@ -236,7 +225,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, isect_array, P, dir, - PATH_RAY_SHADOW, + visibility, object, prim_addr, ray->time, @@ -249,7 +238,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, isect_array, P, dir, - PATH_RAY_SHADOW, + visibility, object, prim_addr, ray->time, @@ -402,7 +391,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg, const Ray *ray, Intersection *isect_array, - const int skip_object, + const uint visibility, const uint max_hits, uint *num_hits) { @@ -411,7 +400,7 @@ ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg, return BVH_FUNCTION_FULL_NAME(QBVH)(kg, ray, isect_array, - skip_object, + visibility, max_hits, num_hits); } @@ -422,7 +411,7 @@ ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg, return BVH_FUNCTION_FULL_NAME(BVH)(kg, ray, isect_array, - skip_object, + visibility, max_hits, num_hits); } diff --git a/intern/cycles/kernel/bvh/bvh_traversal.h b/intern/cycles/kernel/bvh/bvh_traversal.h index c58d3b0316c..bc09237b975 100644 --- a/intern/cycles/kernel/bvh/bvh_traversal.h +++ b/intern/cycles/kernel/bvh/bvh_traversal.h @@ -244,14 +244,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, { /* shadow ray early termination */ #if defined(__KERNEL_SSE2__) - if(visibility == PATH_RAY_SHADOW_OPAQUE) + if(visibility & PATH_RAY_SHADOW_OPAQUE) return true; tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t); # if BVH_FEATURE(BVH_HAIR) tfar = ssef(isect->t); # endif #else - if(visibility == PATH_RAY_SHADOW_OPAQUE) + if(visibility & PATH_RAY_SHADOW_OPAQUE) return true; #endif } @@ -274,14 +274,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, { /* shadow ray early termination */ # if defined(__KERNEL_SSE2__) - if(visibility == PATH_RAY_SHADOW_OPAQUE) + if(visibility & PATH_RAY_SHADOW_OPAQUE) return true; tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t); # if BVH_FEATURE(BVH_HAIR) tfar = ssef(isect->t); # endif # else - if(visibility == PATH_RAY_SHADOW_OPAQUE) + if(visibility & PATH_RAY_SHADOW_OPAQUE) return true; # endif } @@ -328,14 +328,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(hit) { /* shadow ray early termination */ # if defined(__KERNEL_SSE2__) - if(visibility == PATH_RAY_SHADOW_OPAQUE) + if(visibility & PATH_RAY_SHADOW_OPAQUE) return true; tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t); # if BVH_FEATURE(BVH_HAIR) tfar = ssef(isect->t); # endif # else - if(visibility == PATH_RAY_SHADOW_OPAQUE) + if(visibility & PATH_RAY_SHADOW_OPAQUE) return true; # endif } diff --git a/intern/cycles/kernel/bvh/qbvh_shadow_all.h b/intern/cycles/kernel/bvh/qbvh_shadow_all.h index ce474438f2c..0fa8d4323c6 100644 --- a/intern/cycles/kernel/bvh/qbvh_shadow_all.h +++ b/intern/cycles/kernel/bvh/qbvh_shadow_all.h @@ -33,7 +33,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, const Ray *ray, Intersection *isect_array, - const int skip_object, + const uint visibility, const uint max_hits, uint *num_hits) { @@ -107,7 +107,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(false #ifdef __VISIBILITY_FLAG__ - || ((__float_as_uint(inodes.x) & PATH_RAY_SHADOW) == 0) + || ((__float_as_uint(inodes.x) & visibility) == 0) #endif #if BVH_FEATURE(BVH_MOTION) || UNLIKELY(ray->time < inodes.y) @@ -244,7 +244,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(node_addr < 0) { float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1)); #ifdef __VISIBILITY_FLAG__ - if((__float_as_uint(leaf.z) & PATH_RAY_SHADOW) == 0) { + if((__float_as_uint(leaf.z) & visibility) == 0) { /* Pop. */ node_addr = traversal_stack[stack_ptr].addr; --stack_ptr; @@ -268,17 +268,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Primitive intersection. */ while(prim_addr < prim_addr2) { kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) == p_type); - -#ifdef __SHADOW_TRICKS__ - uint tri_object = (object == OBJECT_NONE) - ? kernel_tex_fetch(__prim_object, prim_addr) - : object; - if(tri_object == skip_object) { - ++prim_addr; - continue; - } -#endif - bool hit; /* todo: specialized intersect functions which don't fill in @@ -291,7 +280,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, isect_array, P, dir, - PATH_RAY_SHADOW, + visibility, object, prim_addr); break; @@ -303,7 +292,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, P, dir, ray->time, - PATH_RAY_SHADOW, + visibility, object, prim_addr); break; @@ -318,7 +307,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, isect_array, P, dir, - PATH_RAY_SHADOW, + visibility, object, prim_addr, ray->time, @@ -331,7 +320,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, isect_array, P, dir, - PATH_RAY_SHADOW, + visibility, object, prim_addr, ray->time, diff --git a/intern/cycles/kernel/bvh/qbvh_traversal.h b/intern/cycles/kernel/bvh/qbvh_traversal.h index fca75a1d416..8e0084e3914 100644 --- a/intern/cycles/kernel/bvh/qbvh_traversal.h +++ b/intern/cycles/kernel/bvh/qbvh_traversal.h @@ -340,7 +340,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, prim_addr)) { tfar = ssef(isect->t); /* Shadow ray early termination. */ - if(visibility == PATH_RAY_SHADOW_OPAQUE) { + if(visibility & PATH_RAY_SHADOW_OPAQUE) { return true; } } @@ -362,7 +362,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, prim_addr)) { tfar = ssef(isect->t); /* Shadow ray early termination. */ - if(visibility == PATH_RAY_SHADOW_OPAQUE) { + if(visibility & PATH_RAY_SHADOW_OPAQUE) { return true; } } @@ -409,7 +409,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(hit) { tfar = ssef(isect->t); /* Shadow ray early termination. */ - if(visibility == PATH_RAY_SHADOW_OPAQUE) { + if(visibility & PATH_RAY_SHADOW_OPAQUE) { return true; } } diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index 8f6c2b07381..21564e81b7a 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -649,7 +649,6 @@ ccl_device_inline float kernel_path_integrate(KernelGlobals *kg, state.flag |= (PATH_RAY_SHADOW_CATCHER | PATH_RAY_SHADOW_CATCHER_ONLY | PATH_RAY_STORE_SHADOW_INFO); - state.catcher_object = sd.object; if(!kernel_data.background.transparent) { L->shadow_background_color = indirect_background(kg, &emission_sd, &state, &ray); @@ -783,7 +782,7 @@ ccl_device_inline float kernel_path_integrate(KernelGlobals *kg, #endif /* __SUBSURFACE__ */ #ifdef __SHADOW_TRICKS__ - *is_shadow_catcher = (state.flag & PATH_RAY_SHADOW_CATCHER); + *is_shadow_catcher = (state.flag & PATH_RAY_SHADOW_CATCHER) != 0; #endif /* __SHADOW_TRICKS__ */ #ifdef __KERNEL_DEBUG__ diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h index 77d4f1df447..4ec37d225f7 100644 --- a/intern/cycles/kernel/kernel_path_branched.h +++ b/intern/cycles/kernel/kernel_path_branched.h @@ -502,7 +502,6 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg, state.flag |= (PATH_RAY_SHADOW_CATCHER | PATH_RAY_SHADOW_CATCHER_ONLY | PATH_RAY_STORE_SHADOW_INFO); - state.catcher_object = sd.object; if(!kernel_data.background.transparent) { L->shadow_background_color = indirect_background(kg, &emission_sd, &state, &ray); @@ -628,7 +627,7 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg, } #ifdef __SHADOW_TRICKS__ - *is_shadow_catcher = (state.flag & PATH_RAY_SHADOW_CATCHER); + *is_shadow_catcher = (state.flag & PATH_RAY_SHADOW_CATCHER) != 0; #endif /* __SHADOW_TRICKS__ */ #ifdef __KERNEL_DEBUG__ diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h index a96ffe07718..6fb0b32832e 100644 --- a/intern/cycles/kernel/kernel_path_state.h +++ b/intern/cycles/kernel/kernel_path_state.h @@ -64,10 +64,6 @@ ccl_device_inline void path_state_init(KernelGlobals *kg, state->volume_stack[0].shader = SHADER_NONE; } #endif - -#ifdef __SHADOW_TRICKS__ - state->catcher_object = OBJECT_NONE; -#endif } ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathState *state, int label) diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h index fab5946970d..10e9083551e 100644 --- a/intern/cycles/kernel/kernel_shadow.h +++ b/intern/cycles/kernel/kernel_shadow.h @@ -72,13 +72,14 @@ ccl_device_forceinline bool shadow_handle_transparent_isect( ccl_device bool shadow_blocked_opaque(KernelGlobals *kg, ShaderData *shadow_sd, ccl_addr_space PathState *state, + const uint visibility, Ray *ray, Intersection *isect, float3 *shadow) { const bool blocked = scene_intersect(kg, *ray, - PATH_RAY_SHADOW_OPAQUE, + visibility & PATH_RAY_SHADOW_OPAQUE, isect, NULL, 0.0f, 0.0f); @@ -128,7 +129,7 @@ ccl_device bool shadow_blocked_opaque(KernelGlobals *kg, ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg, ShaderData *shadow_sd, ccl_addr_space PathState *state, - const int skip_object, + const uint visibility, Ray *ray, Intersection *hits, uint max_hits, @@ -141,7 +142,7 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg, const bool blocked = scene_intersect_shadow_all(kg, ray, hits, - skip_object, + visibility, max_hits, &num_hits); /* If no opaque surface found but we did find transparent hits, @@ -218,7 +219,7 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg, ccl_device bool shadow_blocked_transparent_all(KernelGlobals *kg, ShaderData *shadow_sd, ccl_addr_space PathState *state, - const int skip_object, + const uint visibility, Ray *ray, uint max_hits, float3 *shadow) @@ -253,7 +254,7 @@ ccl_device bool shadow_blocked_transparent_all(KernelGlobals *kg, return shadow_blocked_transparent_all_loop(kg, shadow_sd, state, - skip_object, + visibility, ray, hits, max_hits, @@ -278,14 +279,14 @@ ccl_device bool shadow_blocked_transparent_stepped_loop( KernelGlobals *kg, ShaderData *shadow_sd, ccl_addr_space PathState *state, - const int skip_object, + const uint visibility, Ray *ray, Intersection *isect, const bool blocked, const bool is_transparent_isect, float3 *shadow) { - if((blocked && is_transparent_isect) || skip_object != OBJECT_NONE) { + if(blocked && is_transparent_isect) { float3 throughput = make_float3(1.0f, 1.0f, 1.0f); float3 Pend = ray->P + ray->D*ray->t; int bounce = state->transparent_bounce; @@ -304,30 +305,13 @@ ccl_device bool shadow_blocked_transparent_stepped_loop( } if(!scene_intersect(kg, *ray, - PATH_RAY_SHADOW_TRANSPARENT, + visibility & PATH_RAY_SHADOW_TRANSPARENT, isect, NULL, 0.0f, 0.0f)) { break; } -#ifdef __SHADOW_TRICKS__ - if(skip_object != OBJECT_NONE) { - const int isect_object = (isect->object == PRIM_NONE) - ? kernel_tex_fetch(__prim_object, isect->prim) - : isect->object; - if(isect_object == skip_object) { - shader_setup_from_ray(kg, shadow_sd, isect, ray); - /* Move ray forward. */ - ray->P = ray_offset(shadow_sd->P, -shadow_sd->Ng); - if(ray->t != FLT_MAX) { - ray->D = normalize_len(Pend - ray->P, &ray->t); - } - bounce++; - continue; - } - } -#endif if(!shader_transparent_shadow(kg, isect)) { return true; } @@ -373,31 +357,24 @@ ccl_device bool shadow_blocked_transparent_stepped( KernelGlobals *kg, ShaderData *shadow_sd, ccl_addr_space PathState *state, - const int skip_object, + const uint visibility, Ray *ray, Intersection *isect, float3 *shadow) { - bool blocked, is_transparent_isect; - if(skip_object == OBJECT_NONE) { - blocked = scene_intersect(kg, - *ray, - PATH_RAY_SHADOW_OPAQUE, - isect, - NULL, - 0.0f, 0.0f); - is_transparent_isect = blocked - ? shader_transparent_shadow(kg, isect) - : false; - } - else { - blocked = false; - is_transparent_isect = false; - } + bool blocked = scene_intersect(kg, + *ray, + visibility & PATH_RAY_SHADOW_OPAQUE, + isect, + NULL, + 0.0f, 0.0f); + bool is_transparent_isect = blocked + ? shader_transparent_shadow(kg, isect) + : false; return shadow_blocked_transparent_stepped_loop(kg, shadow_sd, state, - skip_object, + visibility, ray, isect, blocked, @@ -422,25 +399,24 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, return false; } #ifdef __SHADOW_TRICKS__ - const int skip_object = state->catcher_object; + const uint visibility = (state->flag & PATH_RAY_SHADOW_CATCHER) + ? PATH_RAY_SHADOW_NON_CATCHER + : PATH_RAY_SHADOW; #else - const int skip_object = OBJECT_NONE; + const uint visibility = PATH_RAY_SHADOW; #endif /* Do actual shadow shading. */ /* First of all, we check if integrator requires transparent shadows. * if not, we use simplest and fastest ever way to calculate occlusion. - * - * NOTE: We can't do quick opaque test here if we are on shadow-catcher - * path because we don't want catcher object to be casting shadow here. */ #ifdef __TRANSPARENT_SHADOWS__ - if(!kernel_data.integrator.transparent_shadows && - skip_object == OBJECT_NONE) + if(!kernel_data.integrator.transparent_shadows) #endif { return shadow_blocked_opaque(kg, shadow_sd, state, + visibility, ray, &isect, shadow); @@ -467,7 +443,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, */ const bool blocked = scene_intersect(kg, *ray, - PATH_RAY_SHADOW_OPAQUE, + visibility & PATH_RAY_SHADOW_OPAQUE, &isect, NULL, 0.0f, 0.0f); @@ -480,7 +456,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, return shadow_blocked_transparent_stepped_loop(kg, shadow_sd, state, - skip_object, + visibility, ray, &isect, blocked, @@ -491,7 +467,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, return shadow_blocked_transparent_all(kg, shadow_sd, state, - skip_object, + visibility, ray, max_hits, shadow); @@ -500,7 +476,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, return shadow_blocked_transparent_stepped(kg, shadow_sd, state, - skip_object, + visibility, ray, &isect, shadow); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 557ce5804f8..90a3c818214 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -330,24 +330,29 @@ enum PathRayFlag { PATH_RAY_SINGULAR = (1 << 5), PATH_RAY_TRANSPARENT = (1 << 6), - PATH_RAY_SHADOW_OPAQUE = (1 << 7), - PATH_RAY_SHADOW_TRANSPARENT = (1 << 8), - PATH_RAY_SHADOW = (PATH_RAY_SHADOW_OPAQUE|PATH_RAY_SHADOW_TRANSPARENT), - - PATH_RAY_CURVE = (1 << 9), /* visibility flag to define curve segments */ - PATH_RAY_VOLUME_SCATTER = (1 << 10), /* volume scattering */ + PATH_RAY_SHADOW_OPAQUE_NON_CATCHER = (1 << 7), + PATH_RAY_SHADOW_OPAQUE_CATCHER = (1 << 8), + PATH_RAY_SHADOW_OPAQUE = (PATH_RAY_SHADOW_OPAQUE_NON_CATCHER|PATH_RAY_SHADOW_OPAQUE_CATCHER), + PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER = (1 << 9), + PATH_RAY_SHADOW_TRANSPARENT_CATCHER = (1 << 10), + PATH_RAY_SHADOW_TRANSPARENT = (PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER|PATH_RAY_SHADOW_TRANSPARENT_CATCHER), + PATH_RAY_SHADOW_NON_CATCHER = (PATH_RAY_SHADOW_OPAQUE_NON_CATCHER|PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER), + PATH_RAY_SHADOW = (PATH_RAY_SHADOW_OPAQUE|PATH_RAY_SHADOW_TRANSPARENT), + + PATH_RAY_CURVE = (1 << 11), /* visibility flag to define curve segments */ + PATH_RAY_VOLUME_SCATTER = (1 << 12), /* volume scattering */ /* Special flag to tag unaligned BVH nodes. */ - PATH_RAY_NODE_UNALIGNED = (1 << 11), + PATH_RAY_NODE_UNALIGNED = (1 << 13), - PATH_RAY_ALL_VISIBILITY = ((1 << 12)-1), + PATH_RAY_ALL_VISIBILITY = ((1 << 14)-1), - PATH_RAY_MIS_SKIP = (1 << 12), - PATH_RAY_DIFFUSE_ANCESTOR = (1 << 13), - PATH_RAY_SINGLE_PASS_DONE = (1 << 14), - PATH_RAY_SHADOW_CATCHER = (1 << 15), - PATH_RAY_SHADOW_CATCHER_ONLY = (1 << 16), - PATH_RAY_STORE_SHADOW_INFO = (1 << 17), + PATH_RAY_MIS_SKIP = (1 << 15), + PATH_RAY_DIFFUSE_ANCESTOR = (1 << 16), + PATH_RAY_SINGLE_PASS_DONE = (1 << 17), + PATH_RAY_SHADOW_CATCHER = (1 << 18), + PATH_RAY_SHADOW_CATCHER_ONLY = (1 << 19), + PATH_RAY_STORE_SHADOW_INFO = (1 << 20), }; /* Closure Label */ @@ -1027,10 +1032,6 @@ typedef struct PathState { RNG rng_congruential; VolumeStack volume_stack[VOLUME_STACK_SIZE]; #endif - -#ifdef __SHADOW_TRICKS__ - int catcher_object; -#endif } PathState; /* Subsurface */ diff --git a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h index fec671be016..916b81faf4e 100644 --- a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h +++ b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h @@ -129,7 +129,6 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao( state->flag |= (PATH_RAY_SHADOW_CATCHER | PATH_RAY_SHADOW_CATCHER_ONLY | PATH_RAY_STORE_SHADOW_INFO); - state->catcher_object = sd->object; if(!kernel_data.background.transparent) { ccl_global Ray *ray = &kernel_split_state.ray[ray_index]; L->shadow_background_color = indirect_background( diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index a794f233718..c337079b09f 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -233,8 +233,10 @@ void OSLShaderManager::shading_system_init() "glossy", /* PATH_RAY_GLOSSY */ "singular", /* PATH_RAY_SINGULAR */ "transparent", /* PATH_RAY_TRANSPARENT */ - "shadow", /* PATH_RAY_SHADOW_OPAQUE */ - "shadow", /* PATH_RAY_SHADOW_TRANSPARENT */ + "shadow", /* PATH_RAY_SHADOW_OPAQUE_NON_CATCHER */ + "shadow", /* PATH_RAY_SHADOW_OPAQUE_CATCHER */ + "shadow", /* PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER */ + "shadow", /* PATH_RAY_SHADOW_TRANSPARENT_CATCHER */ "__unused__", "__unused__", |