Cycles: Revert previous fixes to intersect_all functions

While they prevent legit write past the array boundary error
those fixes introduced regression in behavior when having exact
max_hits transparent intersections and nothing else.

Previous code would have considered such case a totally opaque,
but it's not correct.

Fixes T48941: Some materials don't get transparent shadows anymore
This commit is contained in:
Sergey Sharybin
2016-07-26 16:30:13 +02:00
parent b91aea6096
commit 7030794171
5 changed files with 28 additions and 38 deletions

View File

@@ -254,9 +254,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
/* shadow ray early termination */ /* shadow ray early termination */
if(hit) { if(hit) {
/* Update number of hits now, so we do proper check on max bounces. */
(*num_hits)++;
/* detect if this surface has a shader with transparent shadows */ /* detect if this surface has a shader with transparent shadows */
/* todo: optimize so primitive visibility flag indicates if /* todo: optimize so primitive visibility flag indicates if
@@ -283,15 +280,18 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
return true; return true;
} }
/* if maximum number of hits reached, block all light */ /* if maximum number of hits reached, block all light */
else if(*num_hits >= max_hits) { else if(*num_hits == max_hits) {
return true; return true;
} }
/* move on to next entry in intersections array */
isect_array++;
(*num_hits)++;
#if BVH_FEATURE(BVH_INSTANCING) #if BVH_FEATURE(BVH_INSTANCING)
num_hits_in_instance++; num_hits_in_instance++;
#endif #endif
/* Move on to next entry in intersections array */
isect_array++; isect_array->t = isect_t;
} }
prim_addr++; prim_addr++;

View File

@@ -201,12 +201,14 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
object, object,
prim_addr); prim_addr);
if(hit) { if(hit) {
/* Update number of hits now, so we do proper check on max bounces. */ /* Move on to next entry in intersections array. */
isect_array++;
num_hits++; num_hits++;
#if BVH_FEATURE(BVH_INSTANCING) #if BVH_FEATURE(BVH_INSTANCING)
num_hits_in_instance++; num_hits_in_instance++;
#endif #endif
if(num_hits >= max_hits) { isect_array->t = isect_t;
if(num_hits == max_hits) {
#if BVH_FEATURE(BVH_INSTANCING) #if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION) # if BVH_FEATURE(BVH_MOTION)
float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
@@ -220,9 +222,6 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
#endif /* BVH_FEATURE(BVH_INSTANCING) */ #endif /* BVH_FEATURE(BVH_INSTANCING) */
return num_hits; return num_hits;
} }
/* Move on to next entry in intersections array */
isect_array++;
isect_array->t = isect_t;
} }
} }
break; break;
@@ -247,12 +246,14 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
object, object,
prim_addr); prim_addr);
if(hit) { if(hit) {
/* Update number of hits now, so we do proper check on max bounces. */ /* Move on to next entry in intersections array. */
isect_array++;
num_hits++; num_hits++;
# if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_INSTANCING)
num_hits_in_instance++; num_hits_in_instance++;
# endif # endif
if(num_hits >= max_hits) { isect_array->t = isect_t;
if(num_hits == max_hits) {
# if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION) # if BVH_FEATURE(BVH_MOTION)
float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
@@ -266,9 +267,6 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
# endif /* BVH_FEATURE(BVH_INSTANCING) */ # endif /* BVH_FEATURE(BVH_INSTANCING) */
return num_hits; return num_hits;
} }
/* Move on to next entry in intersections array */
isect_array++;
isect_array->t = isect_t;
} }
} }
break; break;

View File

@@ -337,9 +337,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
/* Shadow ray early termination. */ /* Shadow ray early termination. */
if(hit) { if(hit) {
/* Update number of hits now, so we do proper check on max bounces. */
(*num_hits)++;
/* detect if this surface has a shader with transparent shadows */ /* detect if this surface has a shader with transparent shadows */
/* todo: optimize so primitive visibility flag indicates if /* todo: optimize so primitive visibility flag indicates if
@@ -366,15 +363,17 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
return true; return true;
} }
/* if maximum number of hits reached, block all light */ /* if maximum number of hits reached, block all light */
else if(*num_hits >= max_hits) { else if(*num_hits == max_hits) {
return true; return true;
} }
/* move on to next entry in intersections array */
isect_array++;
(*num_hits)++;
#if BVH_FEATURE(BVH_INSTANCING) #if BVH_FEATURE(BVH_INSTANCING)
num_hits_in_instance++; num_hits_in_instance++;
#endif #endif
/* Move on to next entry in intersections array */
isect_array++;
isect_array->t = isect_t; isect_array->t = isect_t;
} }

View File

@@ -268,12 +268,14 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
/* Intersect ray against primitive. */ /* Intersect ray against primitive. */
hit = triangle_intersect(kg, &isect_precalc, isect_array, P, visibility, object, prim_addr); hit = triangle_intersect(kg, &isect_precalc, isect_array, P, visibility, object, prim_addr);
if(hit) { if(hit) {
/* Update number of hits now, so we do proper check on max bounces. */ /* Move on to next entry in intersections array. */
isect_array++;
num_hits++; num_hits++;
#if BVH_FEATURE(BVH_INSTANCING) #if BVH_FEATURE(BVH_INSTANCING)
num_hits_in_instance++; num_hits_in_instance++;
#endif #endif
if(num_hits >= max_hits) { isect_array->t = isect_t;
if(num_hits == max_hits) {
#if BVH_FEATURE(BVH_INSTANCING) #if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION) # if BVH_FEATURE(BVH_MOTION)
float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
@@ -287,9 +289,6 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
#endif /* BVH_FEATURE(BVH_INSTANCING) */ #endif /* BVH_FEATURE(BVH_INSTANCING) */
return num_hits; return num_hits;
} }
/* Move on to next entry in intersections array */
isect_array++;
isect_array->t = isect_t;
} }
} }
break; break;
@@ -307,12 +306,14 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
/* Intersect ray against primitive. */ /* Intersect ray against primitive. */
hit = motion_triangle_intersect(kg, isect_array, P, dir, ray->time, visibility, object, prim_addr); hit = motion_triangle_intersect(kg, isect_array, P, dir, ray->time, visibility, object, prim_addr);
if(hit) { if(hit) {
/* Update number of hits now, so we do proper check on max bounces. */ /* Move on to next entry in intersections array. */
isect_array++;
num_hits++; num_hits++;
# if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_INSTANCING)
num_hits_in_instance++; num_hits_in_instance++;
# endif # endif
if(num_hits >= max_hits) { isect_array->t = isect_t;
if(num_hits == max_hits) {
# if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_INSTANCING)
# if BVH_FEATURE(BVH_MOTION) # if BVH_FEATURE(BVH_MOTION)
float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir));
@@ -326,9 +327,6 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
# endif /* BVH_FEATURE(BVH_INSTANCING) */ # endif /* BVH_FEATURE(BVH_INSTANCING) */
return num_hits; return num_hits;
} }
/* Move on to next entry in intersections array */
isect_array++;
isect_array->t = isect_t;
} }
} }
break; break;

View File

@@ -75,12 +75,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, ShaderData *shadow_sd,
} }
uint num_hits; uint num_hits;
if(max_hits == 0) { blocked = scene_intersect_shadow_all(kg, ray, hits, max_hits, &num_hits);
blocked = true;
num_hits = 0;
} else {
blocked = scene_intersect_shadow_all(kg, ray, hits, max_hits, &num_hits);
}
/* if no opaque surface found but we did find transparent hits, shade them */ /* if no opaque surface found but we did find transparent hits, shade them */
if(!blocked && num_hits > 0) { if(!blocked && num_hits > 0) {