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.
This commit is contained in:
parent
54a18f6d51
commit
f84cbae43e
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue