diff options
Diffstat (limited to 'intern/cycles/kernel/bvh/bvh.h')
-rw-r--r-- | intern/cycles/kernel/bvh/bvh.h | 577 |
1 files changed, 268 insertions, 309 deletions
diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h index e5f807833f3..13e72ed299f 100644 --- a/intern/cycles/kernel/bvh/bvh.h +++ b/intern/cycles/kernel/bvh/bvh.h @@ -57,19 +57,19 @@ CCL_NAMESPACE_BEGIN #if defined(__HAIR__) # define BVH_FUNCTION_NAME bvh_intersect_hair -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH +# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR | BVH_HAIR_MINIMUM_WIDTH # include "kernel/bvh/bvh_traversal.h" #endif #if defined(__OBJECT_MOTION__) # define BVH_FUNCTION_NAME bvh_intersect_motion -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION +# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_MOTION # include "kernel/bvh/bvh_traversal.h" #endif #if defined(__HAIR__) && defined(__OBJECT_MOTION__) # define BVH_FUNCTION_NAME bvh_intersect_hair_motion -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH|BVH_MOTION +# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR | BVH_HAIR_MINIMUM_WIDTH | BVH_MOTION # include "kernel/bvh/bvh_traversal.h" #endif @@ -82,10 +82,10 @@ CCL_NAMESPACE_BEGIN # if defined(__OBJECT_MOTION__) # define BVH_FUNCTION_NAME bvh_intersect_local_motion -# define BVH_FUNCTION_FEATURES BVH_MOTION|BVH_HAIR +# define BVH_FUNCTION_FEATURES BVH_MOTION | BVH_HAIR # include "kernel/bvh/bvh_local.h" # endif -#endif /* __BVH_LOCAL__ */ +#endif /* __BVH_LOCAL__ */ /* Volume BVH traversal */ @@ -96,16 +96,16 @@ CCL_NAMESPACE_BEGIN # if defined(__INSTANCING__) # define BVH_FUNCTION_NAME bvh_intersect_volume_instancing -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR +# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR # include "kernel/bvh/bvh_volume.h" # endif # if defined(__OBJECT_MOTION__) # define BVH_FUNCTION_NAME bvh_intersect_volume_motion -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION|BVH_HAIR +# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_MOTION | BVH_HAIR # include "kernel/bvh/bvh_volume.h" # endif -#endif /* __VOLUME__ */ +#endif /* __VOLUME__ */ /* Record all intersections - Shadow BVH traversal */ @@ -122,22 +122,22 @@ CCL_NAMESPACE_BEGIN # if defined(__HAIR__) # define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR +# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR # include "kernel/bvh/bvh_shadow_all.h" # endif # if defined(__OBJECT_MOTION__) # define BVH_FUNCTION_NAME bvh_intersect_shadow_all_motion -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION +# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_MOTION # include "kernel/bvh/bvh_shadow_all.h" # endif # if defined(__HAIR__) && defined(__OBJECT_MOTION__) # define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair_motion -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_MOTION +# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR | BVH_MOTION # include "kernel/bvh/bvh_shadow_all.h" # endif -#endif /* __SHADOW_RECORD_ALL__ */ +#endif /* __SHADOW_RECORD_ALL__ */ /* Record all intersections - Volume BVH traversal */ @@ -148,16 +148,16 @@ CCL_NAMESPACE_BEGIN # if defined(__INSTANCING__) # define BVH_FUNCTION_NAME bvh_intersect_volume_all_instancing -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR +# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR # include "kernel/bvh/bvh_volume_all.h" # endif # if defined(__OBJECT_MOTION__) # define BVH_FUNCTION_NAME bvh_intersect_volume_all_motion -# define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION|BVH_HAIR +# define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_MOTION | BVH_HAIR # include "kernel/bvh/bvh_volume_all.h" # endif -#endif /* __VOLUME_RECORD_ALL__ */ +#endif /* __VOLUME_RECORD_ALL__ */ #undef BVH_FEATURE #undef BVH_NAME_JOIN @@ -166,15 +166,15 @@ CCL_NAMESPACE_BEGIN ccl_device_inline bool scene_intersect_valid(const Ray *ray) { - /* NOTE: Due to some vectorization code non-finite origin point might - * cause lots of false-positive intersections which will overflow traversal - * stack. - * This code is a quick way to perform early output, to avoid crashes in - * such cases. - * From production scenes so far it seems it's enough to test first element - * only. - */ - return isfinite(ray->P.x); + /* NOTE: Due to some vectorization code non-finite origin point might + * cause lots of false-positive intersections which will overflow traversal + * stack. + * This code is a quick way to perform early output, to avoid crashes in + * such cases. + * From production scenes so far it seems it's enough to test first element + * only. + */ + return isfinite(ray->P.x); } /* Note: ray is passed by value to work around a possible CUDA compiler bug. */ @@ -186,59 +186,60 @@ ccl_device_intersect bool scene_intersect(KernelGlobals *kg, float difl, float extmax) { - PROFILING_INIT(kg, PROFILING_INTERSECT); + PROFILING_INIT(kg, PROFILING_INTERSECT); - if(!scene_intersect_valid(&ray)) { - return false; - } + if (!scene_intersect_valid(&ray)) { + return false; + } #ifdef __EMBREE__ - if(kernel_data.bvh.scene) { - isect->t = ray.t; - CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_REGULAR); - IntersectContext rtc_ctx(&ctx); - RTCRayHit ray_hit; - kernel_embree_setup_rayhit(ray, ray_hit, visibility); - rtcIntersect1(kernel_data.bvh.scene, &rtc_ctx.context, &ray_hit); - if(ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID && ray_hit.hit.primID != RTC_INVALID_GEOMETRY_ID) { - kernel_embree_convert_hit(kg, &ray_hit.ray, &ray_hit.hit, isect); - return true; - } - return false; - } -#endif /* __EMBREE__ */ + if (kernel_data.bvh.scene) { + isect->t = ray.t; + CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_REGULAR); + IntersectContext rtc_ctx(&ctx); + RTCRayHit ray_hit; + kernel_embree_setup_rayhit(ray, ray_hit, visibility); + rtcIntersect1(kernel_data.bvh.scene, &rtc_ctx.context, &ray_hit); + if (ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID && + ray_hit.hit.primID != RTC_INVALID_GEOMETRY_ID) { + kernel_embree_convert_hit(kg, &ray_hit.ray, &ray_hit.hit, isect); + return true; + } + return false; + } +#endif /* __EMBREE__ */ #ifdef __OBJECT_MOTION__ - if(kernel_data.bvh.have_motion) { + if (kernel_data.bvh.have_motion) { # ifdef __HAIR__ - if(kernel_data.bvh.have_curves) - return bvh_intersect_hair_motion(kg, &ray, isect, visibility, lcg_state, difl, extmax); -# endif /* __HAIR__ */ + if (kernel_data.bvh.have_curves) + return bvh_intersect_hair_motion(kg, &ray, isect, visibility, lcg_state, difl, extmax); +# endif /* __HAIR__ */ - return bvh_intersect_motion(kg, &ray, isect, visibility); - } -#endif /* __OBJECT_MOTION__ */ + return bvh_intersect_motion(kg, &ray, isect, visibility); + } +#endif /* __OBJECT_MOTION__ */ #ifdef __HAIR__ - if(kernel_data.bvh.have_curves) - return bvh_intersect_hair(kg, &ray, isect, visibility, lcg_state, difl, extmax); -#endif /* __HAIR__ */ + if (kernel_data.bvh.have_curves) + return bvh_intersect_hair(kg, &ray, isect, visibility, lcg_state, difl, extmax); +#endif /* __HAIR__ */ #ifdef __KERNEL_CPU__ # ifdef __INSTANCING__ - if(kernel_data.bvh.have_instancing) - return bvh_intersect_instancing(kg, &ray, isect, visibility); -# endif /* __INSTANCING__ */ + if (kernel_data.bvh.have_instancing) + return bvh_intersect_instancing(kg, &ray, isect, visibility); +# endif /* __INSTANCING__ */ - return bvh_intersect(kg, &ray, isect, visibility); -#else /* __KERNEL_CPU__ */ + return bvh_intersect(kg, &ray, isect, visibility); +#else /* __KERNEL_CPU__ */ # ifdef __INSTANCING__ - return bvh_intersect_instancing(kg, &ray, isect, visibility); + return bvh_intersect_instancing(kg, &ray, isect, visibility); # else - return bvh_intersect(kg, &ray, isect, visibility); -# endif /* __INSTANCING__ */ + return bvh_intersect(kg, &ray, isect, visibility); +# endif /* __INSTANCING__ */ -#endif /* __KERNEL_CPU__ */ +#endif /* __KERNEL_CPU__ */ } #ifdef __BVH_LOCAL__ @@ -250,77 +251,61 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals *kg, uint *lcg_state, int max_hits) { - PROFILING_INIT(kg, PROFILING_INTERSECT_LOCAL); + PROFILING_INIT(kg, PROFILING_INTERSECT_LOCAL); - if(!scene_intersect_valid(&ray)) { - local_isect->num_hits = 0; - return false; - } -#ifdef __EMBREE__ - if(kernel_data.bvh.scene) { - CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SSS); - ctx.lcg_state = lcg_state; - ctx.max_hits = max_hits; - ctx.ss_isect = local_isect; - local_isect->num_hits = 0; - ctx.sss_object_id = local_object; - IntersectContext rtc_ctx(&ctx); - RTCRay rtc_ray; - kernel_embree_setup_ray(ray, rtc_ray, PATH_RAY_ALL_VISIBILITY); - - /* Get the Embree scene for this intersection. */ - RTCGeometry geom = rtcGetGeometry(kernel_data.bvh.scene, local_object * 2); - if(geom) { - float3 P = ray.P; - float3 dir = ray.D; - float3 idir = ray.D; - const int object_flag = kernel_tex_fetch(__object_flag, local_object); - if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { - Transform ob_itfm; - rtc_ray.tfar = bvh_instance_motion_push(kg, - local_object, - &ray, - &P, - &dir, - &idir, - ray.t, - &ob_itfm); - /* bvh_instance_motion_push() returns the inverse transform but - * it's not needed here. */ - (void) ob_itfm; - - rtc_ray.org_x = P.x; - rtc_ray.org_y = P.y; - rtc_ray.org_z = P.z; - rtc_ray.dir_x = dir.x; - rtc_ray.dir_y = dir.y; - rtc_ray.dir_z = dir.z; - } - RTCScene scene = (RTCScene)rtcGetGeometryUserData(geom); - if(scene) { - rtcOccluded1(scene, &rtc_ctx.context, &rtc_ray); - } - } - - return local_isect->num_hits > 0; - } -#endif /* __EMBREE__ */ -#ifdef __OBJECT_MOTION__ - if(kernel_data.bvh.have_motion) { - return bvh_intersect_local_motion(kg, - &ray, - local_isect, - local_object, - lcg_state, - max_hits); - } -#endif /* __OBJECT_MOTION__ */ - return bvh_intersect_local(kg, - &ray, - local_isect, - local_object, - lcg_state, - max_hits); + if (!scene_intersect_valid(&ray)) { + local_isect->num_hits = 0; + return false; + } +# ifdef __EMBREE__ + if (kernel_data.bvh.scene) { + CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SSS); + ctx.lcg_state = lcg_state; + ctx.max_hits = max_hits; + ctx.ss_isect = local_isect; + local_isect->num_hits = 0; + ctx.sss_object_id = local_object; + IntersectContext rtc_ctx(&ctx); + RTCRay rtc_ray; + kernel_embree_setup_ray(ray, rtc_ray, PATH_RAY_ALL_VISIBILITY); + + /* Get the Embree scene for this intersection. */ + RTCGeometry geom = rtcGetGeometry(kernel_data.bvh.scene, local_object * 2); + if (geom) { + float3 P = ray.P; + float3 dir = ray.D; + float3 idir = ray.D; + const int object_flag = kernel_tex_fetch(__object_flag, local_object); + if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { + Transform ob_itfm; + rtc_ray.tfar = bvh_instance_motion_push( + kg, local_object, &ray, &P, &dir, &idir, ray.t, &ob_itfm); + /* bvh_instance_motion_push() returns the inverse transform but + * it's not needed here. */ + (void)ob_itfm; + + rtc_ray.org_x = P.x; + rtc_ray.org_y = P.y; + rtc_ray.org_z = P.z; + rtc_ray.dir_x = dir.x; + rtc_ray.dir_y = dir.y; + rtc_ray.dir_z = dir.z; + } + RTCScene scene = (RTCScene)rtcGetGeometryUserData(geom); + if (scene) { + rtcOccluded1(scene, &rtc_ctx.context, &rtc_ray); + } + } + + return local_isect->num_hits > 0; + } +# endif /* __EMBREE__ */ +# ifdef __OBJECT_MOTION__ + if (kernel_data.bvh.have_motion) { + return bvh_intersect_local_motion(kg, &ray, local_isect, local_object, lcg_state, max_hits); + } +# endif /* __OBJECT_MOTION__ */ + return bvh_intersect_local(kg, &ray, local_isect, local_object, lcg_state, max_hits); } #endif @@ -332,82 +317,57 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg, uint max_hits, uint *num_hits) { - PROFILING_INIT(kg, PROFILING_INTERSECT_SHADOW_ALL); + PROFILING_INIT(kg, PROFILING_INTERSECT_SHADOW_ALL); - if(!scene_intersect_valid(ray)) { - *num_hits = 0; - return false; - } + if (!scene_intersect_valid(ray)) { + *num_hits = 0; + return false; + } # ifdef __EMBREE__ - if(kernel_data.bvh.scene) { - CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SHADOW_ALL); - ctx.isect_s = isect; - ctx.max_hits = max_hits; - ctx.num_hits = 0; - IntersectContext rtc_ctx(&ctx); - RTCRay rtc_ray; - kernel_embree_setup_ray(*ray, rtc_ray, PATH_RAY_SHADOW); - rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray); - - if(ctx.num_hits > max_hits) { - return true; - } - *num_hits = ctx.num_hits; - return rtc_ray.tfar == -INFINITY; - } + if (kernel_data.bvh.scene) { + CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SHADOW_ALL); + ctx.isect_s = isect; + ctx.max_hits = max_hits; + ctx.num_hits = 0; + IntersectContext rtc_ctx(&ctx); + RTCRay rtc_ray; + kernel_embree_setup_ray(*ray, rtc_ray, PATH_RAY_SHADOW); + rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray); + + if (ctx.num_hits > max_hits) { + return true; + } + *num_hits = ctx.num_hits; + return rtc_ray.tfar == -INFINITY; + } # endif # ifdef __OBJECT_MOTION__ - if(kernel_data.bvh.have_motion) { + if (kernel_data.bvh.have_motion) { # ifdef __HAIR__ - if(kernel_data.bvh.have_curves) { - return bvh_intersect_shadow_all_hair_motion(kg, - ray, - isect, - visibility, - max_hits, - num_hits); - } -# endif /* __HAIR__ */ - - return bvh_intersect_shadow_all_motion(kg, - ray, - isect, - visibility, - max_hits, - num_hits); - } -# endif /* __OBJECT_MOTION__ */ + if (kernel_data.bvh.have_curves) { + return bvh_intersect_shadow_all_hair_motion(kg, ray, isect, visibility, max_hits, num_hits); + } +# endif /* __HAIR__ */ + + return bvh_intersect_shadow_all_motion(kg, ray, isect, visibility, max_hits, num_hits); + } +# endif /* __OBJECT_MOTION__ */ # ifdef __HAIR__ - if(kernel_data.bvh.have_curves) { - return bvh_intersect_shadow_all_hair(kg, - ray, - isect, - visibility, - max_hits, - num_hits); - } -# endif /* __HAIR__ */ + if (kernel_data.bvh.have_curves) { + return bvh_intersect_shadow_all_hair(kg, ray, isect, visibility, max_hits, num_hits); + } +# endif /* __HAIR__ */ # ifdef __INSTANCING__ - if(kernel_data.bvh.have_instancing) { - return bvh_intersect_shadow_all_instancing(kg, - ray, - isect, - visibility, - max_hits, - num_hits); - } -# endif /* __INSTANCING__ */ - - return bvh_intersect_shadow_all(kg, - ray, - isect, - visibility, - max_hits, - num_hits); + if (kernel_data.bvh.have_instancing) { + return bvh_intersect_shadow_all_instancing(kg, ray, isect, visibility, max_hits, num_hits); + } +# endif /* __INSTANCING__ */ + + return bvh_intersect_shadow_all(kg, ray, isect, visibility, max_hits, num_hits); } -#endif /* __SHADOW_RECORD_ALL__ */ +#endif /* __SHADOW_RECORD_ALL__ */ #ifdef __VOLUME__ ccl_device_intersect bool scene_intersect_volume(KernelGlobals *kg, @@ -415,31 +375,31 @@ ccl_device_intersect bool scene_intersect_volume(KernelGlobals *kg, Intersection *isect, const uint visibility) { - PROFILING_INIT(kg, PROFILING_INTERSECT_VOLUME); + PROFILING_INIT(kg, PROFILING_INTERSECT_VOLUME); - if(!scene_intersect_valid(ray)) { - return false; - } + if (!scene_intersect_valid(ray)) { + return false; + } # ifdef __OBJECT_MOTION__ - if(kernel_data.bvh.have_motion) { - return bvh_intersect_volume_motion(kg, ray, isect, visibility); - } -# endif /* __OBJECT_MOTION__ */ + if (kernel_data.bvh.have_motion) { + return bvh_intersect_volume_motion(kg, ray, isect, visibility); + } +# endif /* __OBJECT_MOTION__ */ # ifdef __KERNEL_CPU__ # ifdef __INSTANCING__ - if(kernel_data.bvh.have_instancing) - return bvh_intersect_volume_instancing(kg, ray, isect, visibility); -# endif /* __INSTANCING__ */ - return bvh_intersect_volume(kg, ray, isect, visibility); -# else /* __KERNEL_CPU__ */ + if (kernel_data.bvh.have_instancing) + return bvh_intersect_volume_instancing(kg, ray, isect, visibility); +# endif /* __INSTANCING__ */ + return bvh_intersect_volume(kg, ray, isect, visibility); +# else /* __KERNEL_CPU__ */ # ifdef __INSTANCING__ - return bvh_intersect_volume_instancing(kg, ray, isect, visibility); + return bvh_intersect_volume_instancing(kg, ray, isect, visibility); # else - return bvh_intersect_volume(kg, ray, isect, visibility); -# endif /* __INSTANCING__ */ -# endif /* __KERNEL_CPU__ */ + return bvh_intersect_volume(kg, ray, isect, visibility); +# endif /* __INSTANCING__ */ +# endif /* __KERNEL_CPU__ */ } -#endif /* __VOLUME__ */ +#endif /* __VOLUME__ */ #ifdef __VOLUME_RECORD_ALL__ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg, @@ -448,37 +408,36 @@ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg, const uint max_hits, const uint visibility) { - PROFILING_INIT(kg, PROFILING_INTERSECT_VOLUME_ALL); + PROFILING_INIT(kg, PROFILING_INTERSECT_VOLUME_ALL); - if(!scene_intersect_valid(ray)) { - return false; - } + if (!scene_intersect_valid(ray)) { + return false; + } # ifdef __EMBREE__ - if(kernel_data.bvh.scene) { - CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_VOLUME_ALL); - ctx.isect_s = isect; - ctx.max_hits = max_hits; - ctx.num_hits = 0; - IntersectContext rtc_ctx(&ctx); - RTCRay rtc_ray; - kernel_embree_setup_ray(*ray, rtc_ray, visibility); - rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray); - return rtc_ray.tfar == -INFINITY; - } + if (kernel_data.bvh.scene) { + CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_VOLUME_ALL); + ctx.isect_s = isect; + ctx.max_hits = max_hits; + ctx.num_hits = 0; + IntersectContext rtc_ctx(&ctx); + RTCRay rtc_ray; + kernel_embree_setup_ray(*ray, rtc_ray, visibility); + rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray); + return rtc_ray.tfar == -INFINITY; + } # endif # ifdef __OBJECT_MOTION__ - if(kernel_data.bvh.have_motion) { - return bvh_intersect_volume_all_motion(kg, ray, isect, max_hits, visibility); - } -# endif /* __OBJECT_MOTION__ */ + if (kernel_data.bvh.have_motion) { + return bvh_intersect_volume_all_motion(kg, ray, isect, max_hits, visibility); + } +# endif /* __OBJECT_MOTION__ */ # ifdef __INSTANCING__ - if(kernel_data.bvh.have_instancing) - return bvh_intersect_volume_all_instancing(kg, ray, isect, max_hits, visibility); -# endif /* __INSTANCING__ */ - return bvh_intersect_volume_all(kg, ray, isect, max_hits, visibility); + if (kernel_data.bvh.have_instancing) + return bvh_intersect_volume_all_instancing(kg, ray, isect, max_hits, visibility); +# endif /* __INSTANCING__ */ + return bvh_intersect_volume_all(kg, ray, isect, max_hits, visibility); } -#endif /* __VOLUME_RECORD_ALL__ */ - +#endif /* __VOLUME_RECORD_ALL__ */ /* Ray offset to avoid self intersection. * @@ -488,48 +447,48 @@ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg, ccl_device_inline float3 ray_offset(float3 P, float3 Ng) { #ifdef __INTERSECTION_REFINE__ - const float epsilon_f = 1e-5f; - /* ideally this should match epsilon_f, but instancing and motion blur - * precision makes it problematic */ - const float epsilon_test = 1.0f; - const int epsilon_i = 32; - - float3 res; - - /* x component */ - if(fabsf(P.x) < epsilon_test) { - res.x = P.x + Ng.x*epsilon_f; - } - else { - uint ix = __float_as_uint(P.x); - ix += ((ix ^ __float_as_uint(Ng.x)) >> 31)? -epsilon_i: epsilon_i; - res.x = __uint_as_float(ix); - } - - /* y component */ - if(fabsf(P.y) < epsilon_test) { - res.y = P.y + Ng.y*epsilon_f; - } - else { - uint iy = __float_as_uint(P.y); - iy += ((iy ^ __float_as_uint(Ng.y)) >> 31)? -epsilon_i: epsilon_i; - res.y = __uint_as_float(iy); - } - - /* z component */ - if(fabsf(P.z) < epsilon_test) { - res.z = P.z + Ng.z*epsilon_f; - } - else { - uint iz = __float_as_uint(P.z); - iz += ((iz ^ __float_as_uint(Ng.z)) >> 31)? -epsilon_i: epsilon_i; - res.z = __uint_as_float(iz); - } - - return res; + const float epsilon_f = 1e-5f; + /* ideally this should match epsilon_f, but instancing and motion blur + * precision makes it problematic */ + const float epsilon_test = 1.0f; + const int epsilon_i = 32; + + float3 res; + + /* x component */ + if (fabsf(P.x) < epsilon_test) { + res.x = P.x + Ng.x * epsilon_f; + } + else { + uint ix = __float_as_uint(P.x); + ix += ((ix ^ __float_as_uint(Ng.x)) >> 31) ? -epsilon_i : epsilon_i; + res.x = __uint_as_float(ix); + } + + /* y component */ + if (fabsf(P.y) < epsilon_test) { + res.y = P.y + Ng.y * epsilon_f; + } + else { + uint iy = __float_as_uint(P.y); + iy += ((iy ^ __float_as_uint(Ng.y)) >> 31) ? -epsilon_i : epsilon_i; + res.y = __uint_as_float(iy); + } + + /* z component */ + if (fabsf(P.z) < epsilon_test) { + res.z = P.z + Ng.z * epsilon_f; + } + else { + uint iz = __float_as_uint(P.z); + iz += ((iz ^ __float_as_uint(Ng.z)) >> 31) ? -epsilon_i : epsilon_i; + res.z = __uint_as_float(iz); + } + + return res; #else - const float epsilon_f = 1e-4f; - return P + epsilon_f*Ng; + const float epsilon_f = 1e-4f; + return P + epsilon_f * Ng; #endif } @@ -537,40 +496,40 @@ ccl_device_inline float3 ray_offset(float3 P, float3 Ng) /* ToDo: Move to another file? */ ccl_device int intersections_compare(const void *a, const void *b) { - const Intersection *isect_a = (const Intersection*)a; - const Intersection *isect_b = (const Intersection*)b; - - if(isect_a->t < isect_b->t) - return -1; - else if(isect_a->t > isect_b->t) - return 1; - else - return 0; + const Intersection *isect_a = (const Intersection *)a; + const Intersection *isect_b = (const Intersection *)b; + + if (isect_a->t < isect_b->t) + return -1; + else if (isect_a->t > isect_b->t) + return 1; + else + return 0; } #endif #if defined(__SHADOW_RECORD_ALL__) ccl_device_inline void sort_intersections(Intersection *hits, uint num_hits) { -#ifdef __KERNEL_GPU__ - /* Use bubble sort which has more friendly memory pattern on GPU. */ - bool swapped; - do { - swapped = false; - for(int j = 0; j < num_hits - 1; ++j) { - if(hits[j].t > hits[j + 1].t) { - struct Intersection tmp = hits[j]; - hits[j] = hits[j + 1]; - hits[j + 1] = tmp; - swapped = true; - } - } - --num_hits; - } while(swapped); -#else - qsort(hits, num_hits, sizeof(Intersection), intersections_compare); -#endif +# ifdef __KERNEL_GPU__ + /* Use bubble sort which has more friendly memory pattern on GPU. */ + bool swapped; + do { + swapped = false; + for (int j = 0; j < num_hits - 1; ++j) { + if (hits[j].t > hits[j + 1].t) { + struct Intersection tmp = hits[j]; + hits[j] = hits[j + 1]; + hits[j + 1] = tmp; + swapped = true; + } + } + --num_hits; + } while (swapped); +# else + qsort(hits, num_hits, sizeof(Intersection), intersections_compare); +# endif } -#endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */ +#endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */ CCL_NAMESPACE_END |