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
This commit is contained in:
Brecht Van Lommel 2017-08-01 23:40:38 +02:00
parent dc213ca066
commit 8b73c9a437
15 changed files with 98 additions and 136 deletions

View File

@ -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;

View File

@ -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(). */

View File

@ -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(),

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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
}

View File

@ -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,

View File

@ -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;
}
}

View File

@ -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__

View File

@ -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__

View File

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

View File

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

View File

@ -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_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 << 9), /* visibility flag to define curve segments */
PATH_RAY_VOLUME_SCATTER = (1 << 10), /* volume scattering */
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 */

View File

@ -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(

View File

@ -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__",