From 70307941715f1274b9ca7f859fcc93ab5f5c5c66 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 26 Jul 2016 16:30:13 +0200 Subject: [PATCH] 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 --- intern/cycles/kernel/bvh/bvh_shadow_all.h | 12 ++++++------ intern/cycles/kernel/bvh/bvh_volume_all.h | 18 ++++++++---------- intern/cycles/kernel/bvh/qbvh_shadow_all.h | 11 +++++------ intern/cycles/kernel/bvh/qbvh_volume_all.h | 18 ++++++++---------- intern/cycles/kernel/kernel_shadow.h | 7 +------ 5 files changed, 28 insertions(+), 38 deletions(-) diff --git a/intern/cycles/kernel/bvh/bvh_shadow_all.h b/intern/cycles/kernel/bvh/bvh_shadow_all.h index b27afaa9869..1d6fa303d3e 100644 --- a/intern/cycles/kernel/bvh/bvh_shadow_all.h +++ b/intern/cycles/kernel/bvh/bvh_shadow_all.h @@ -254,9 +254,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, /* shadow ray early termination */ 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 */ /* todo: optimize so primitive visibility flag indicates if @@ -283,15 +280,18 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, return true; } /* if maximum number of hits reached, block all light */ - else if(*num_hits >= max_hits) { + else if(*num_hits == max_hits) { return true; } + /* move on to next entry in intersections array */ + isect_array++; + (*num_hits)++; #if BVH_FEATURE(BVH_INSTANCING) num_hits_in_instance++; #endif - /* Move on to next entry in intersections array */ - isect_array++; + + isect_array->t = isect_t; } prim_addr++; diff --git a/intern/cycles/kernel/bvh/bvh_volume_all.h b/intern/cycles/kernel/bvh/bvh_volume_all.h index d7f6bf86c71..7eddc2891d0 100644 --- a/intern/cycles/kernel/bvh/bvh_volume_all.h +++ b/intern/cycles/kernel/bvh/bvh_volume_all.h @@ -201,12 +201,14 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, object, prim_addr); 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++; #if BVH_FEATURE(BVH_INSTANCING) num_hits_in_instance++; #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_MOTION) 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) */ return num_hits; } - /* Move on to next entry in intersections array */ - isect_array++; - isect_array->t = isect_t; } } break; @@ -247,12 +246,14 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, object, prim_addr); 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++; # if BVH_FEATURE(BVH_INSTANCING) num_hits_in_instance++; # 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_MOTION) 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) */ return num_hits; } - /* Move on to next entry in intersections array */ - isect_array++; - isect_array->t = isect_t; } } break; diff --git a/intern/cycles/kernel/bvh/qbvh_shadow_all.h b/intern/cycles/kernel/bvh/qbvh_shadow_all.h index eb98eaf7455..3a728b388eb 100644 --- a/intern/cycles/kernel/bvh/qbvh_shadow_all.h +++ b/intern/cycles/kernel/bvh/qbvh_shadow_all.h @@ -337,9 +337,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Shadow ray early termination. */ 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 */ /* todo: optimize so primitive visibility flag indicates if @@ -366,15 +363,17 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, return true; } /* if maximum number of hits reached, block all light */ - else if(*num_hits >= max_hits) { + else if(*num_hits == max_hits) { return true; } + /* move on to next entry in intersections array */ + isect_array++; + (*num_hits)++; #if BVH_FEATURE(BVH_INSTANCING) num_hits_in_instance++; #endif - /* Move on to next entry in intersections array */ - isect_array++; + isect_array->t = isect_t; } diff --git a/intern/cycles/kernel/bvh/qbvh_volume_all.h b/intern/cycles/kernel/bvh/qbvh_volume_all.h index 90cad9d91c0..4d3028b37bf 100644 --- a/intern/cycles/kernel/bvh/qbvh_volume_all.h +++ b/intern/cycles/kernel/bvh/qbvh_volume_all.h @@ -268,12 +268,14 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Intersect ray against primitive. */ hit = triangle_intersect(kg, &isect_precalc, isect_array, P, visibility, object, prim_addr); 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++; #if BVH_FEATURE(BVH_INSTANCING) num_hits_in_instance++; #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_MOTION) 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) */ return num_hits; } - /* Move on to next entry in intersections array */ - isect_array++; - isect_array->t = isect_t; } } break; @@ -307,12 +306,14 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Intersect ray against primitive. */ hit = motion_triangle_intersect(kg, isect_array, P, dir, ray->time, visibility, object, prim_addr); 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++; # if BVH_FEATURE(BVH_INSTANCING) num_hits_in_instance++; # 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_MOTION) 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) */ return num_hits; } - /* Move on to next entry in intersections array */ - isect_array++; - isect_array->t = isect_t; } } break; diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h index d1576754d2e..db2fc84834a 100644 --- a/intern/cycles/kernel/kernel_shadow.h +++ b/intern/cycles/kernel/kernel_shadow.h @@ -75,12 +75,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, ShaderData *shadow_sd, } uint num_hits; - if(max_hits == 0) { - blocked = true; - num_hits = 0; - } else { - blocked = scene_intersect_shadow_all(kg, ray, hits, max_hits, &num_hits); - } + 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(!blocked && num_hits > 0) {