Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2015-10-22 20:06:25 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-10-22 20:07:28 +0300
commitf84cbae43e3ef2538b8458339beb60ef5dc3a2e5 (patch)
tree440935acf71b2f9610e6d832e4d55e27abe30a63 /intern
parent54a18f6d51db40d0bca7be1f92c8b11f4ff881e4 (diff)
Cycles: Fix for watertight intersection
It was possible to miss some intersection caused by wrong barycentric coordinates sign. Cases when one of the coordinate is zero and other are negative was not handled correct.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/geom/geom_triangle_intersect.h13
1 files changed, 5 insertions, 8 deletions
diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h
index ba309a1dc53..1ce4eea48f4 100644
--- a/intern/cycles/kernel/geom/geom_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h
@@ -142,12 +142,8 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
float U = Cx * By - Cy * Bx;
float V = Ax * Cy - Ay * Cx;
float W = Bx * Ay - By * Ax;
- const int sign_mask = (__float_as_int(U) & 0x80000000);
- /* TODO(sergey): Check if multiplication plus sign check is faster
- * or at least same speed (but robust for endian types).
- */
- if(sign_mask != (__float_as_int(V) & 0x80000000) ||
- sign_mask != (__float_as_int(W) & 0x80000000))
+ if ((U < 0.0f || V < 0.0f || W < 0.0f) &&
+ (U > 0.0f || V > 0.0f || W > 0.0f))
{
return false;
}
@@ -162,9 +158,10 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
* the hit distance.
*/
const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz;
- const float sign_T = xor_signmask(T, sign_mask);
+ const int sign_det = (__float_as_int(det) & 0x80000000);
+ const float sign_T = xor_signmask(T, sign_det);
if((sign_T < 0.0f) ||
- (sign_T > isect->t * xor_signmask(det, sign_mask)))
+ (sign_T > isect->t * xor_signmask(det, sign_det)))
{
return false;
}