diff options
Diffstat (limited to 'intern/cycles/kernel/device/metal/kernel.metal')
-rw-r--r-- | intern/cycles/kernel/device/metal/kernel.metal | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/intern/cycles/kernel/device/metal/kernel.metal b/intern/cycles/kernel/device/metal/kernel.metal index 3303b541487..6b77940660f 100644 --- a/intern/cycles/kernel/device/metal/kernel.metal +++ b/intern/cycles/kernel/device/metal/kernel.metal @@ -40,6 +40,27 @@ struct TriangleIntersectionResult enum { METALRT_HIT_TRIANGLE, METALRT_HIT_BOUNDING_BOX }; +ccl_device_inline bool intersection_skip_self(ray_data const RaySelfPrimitives& self, + const int object, + const int prim) +{ + return (self.prim == prim) && (self.object == object); +} + +ccl_device_inline bool intersection_skip_self_shadow(ray_data const RaySelfPrimitives& self, + const int object, + const int prim) +{ + return ((self.prim == prim) && (self.object == object)) || + ((self.light_prim == prim) && (self.light_object == object)); +} + +ccl_device_inline bool intersection_skip_self_local(ray_data const RaySelfPrimitives& self, + const int prim) +{ + return (self.prim == prim); +} + template<typename TReturn, uint intersection_type> TReturn metalrt_local_hit(constant KernelParamsMetal &launch_params_metal, ray_data MetalKernelContext::MetalRTIntersectionLocalPayload &payload, @@ -53,8 +74,8 @@ TReturn metalrt_local_hit(constant KernelParamsMetal &launch_params_metal, #ifdef __BVH_LOCAL__ uint prim = primitive_id + kernel_tex_fetch(__object_prim_offset, object); - if (object != payload.local_object) { - /* Only intersect with matching object */ + if ((object != payload.local_object) || intersection_skip_self_local(payload.self, prim)) { + /* Only intersect with matching object and skip self-intersecton. */ result.accept = false; result.continue_search = true; return result; @@ -166,6 +187,11 @@ bool metalrt_shadow_all_hit(constant KernelParamsMetal &launch_params_metal, } # endif + if (intersection_skip_self_shadow(payload.self, object, prim)) { + /* continue search */ + return true; + } + float u = 0.0f, v = 0.0f; int type = 0; if (intersection_type == METALRT_HIT_TRIANGLE) { @@ -322,21 +348,35 @@ inline TReturnType metalrt_visibility_test(constant KernelParamsMetal &launch_pa } # endif -# ifdef __VISIBILITY_FLAG__ uint visibility = payload.visibility; +# ifdef __VISIBILITY_FLAG__ if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) { result.accept = false; result.continue_search = true; return result; } +# endif /* Shadow ray early termination. */ if (visibility & PATH_RAY_SHADOW_OPAQUE) { - result.accept = true; - result.continue_search = false; - return result; + if (intersection_skip_self_shadow(payload.self, object, prim)) { + result.accept = false; + result.continue_search = true; + return result; + } + else { + result.accept = true; + result.continue_search = false; + return result; + } + } + else { + if (intersection_skip_self(payload.self, object, prim)) { + result.accept = false; + result.continue_search = true; + return result; + } } -# endif result.accept = true; result.continue_search = true; |