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-03-05 16:55:30 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-03-05 16:55:30 +0300
commit9489205c5c0b9b432d02be4a3d0d15fc62ee6cb9 (patch)
tree3888e597a1eb7c96bd375fd45741621fb2c805a9 /intern
parenteb16b04b9dac7703042048f676b832894784244e (diff)
Fix T43865: Cycles: Watertight rendering produces artifacts on a huge plane
The issue was caused by numerical instability whrn having ray origin close to a huge triangle, which could have aused bad ray distance check. Watertight Woop intersection isn't really addressing such cases, it's dealing with small triangles far away from the ray origin instead, so it's a bit tricky yo make it working reliably. While we're quite close to the release it's safer to do check in Pleaucker coordinates if ray close to a huge triangle. Likely this additional check combined with some other tweaks to the code doesn't cause measurable slowdown in the scenes tested here. After the release we can play a bit more with this code in order to make it more stable without Pleucker fallback.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/geom/geom_triangle_intersect.h43
1 files changed, 35 insertions, 8 deletions
diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h
index 6defa80fd01..06917dc16d8 100644
--- a/intern/cycles/kernel/geom/geom_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h
@@ -153,14 +153,16 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
/* Calculate scaled z−coordinates of vertices and use them to calculate
* the hit distance.
*/
- const float Az = Sz * A_kz;
- const float Bz = Sz * B_kz;
- const float Cz = Sz * C_kz;
- const float T = U * Az + V * Bz + W * Cz;
+ const float T = (U * A_kz + V * B_kz + W * C_kz) * Sz;
- if ((xor_signmast(T, sign_mask) < 0.0f) ||
- (xor_signmast(T, sign_mask) > isect->t * xor_signmast(det, sign_mask)))
- {
+ /* Perform "near clipping". */
+ const float abs_T = xor_signmast(T, sign_mask);
+ if(abs_T < 0.0f) {
+ return false;
+ }
+ /* Perform "far clipping". */
+ const float abs_det = xor_signmast(det, sign_mask);
+ if(abs_T > isect->t * abs_det) {
return false;
}
@@ -172,12 +174,37 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
{
/* Normalize U, V, W, and T. */
const float inv_det = 1.0f / det;
+ const float t = T * inv_det;
+
+#ifdef __INTERSECTION_REFINE__
+ /* TODO(sergey): When intersection refine is enabled ray is being
+ * pushed by quite small epsilon from the surface, which causes
+ * numerical issues of watertight Woop intersection check with
+ * huge triangles.
+ *
+ * Here we're working this around by checking distance in Pleucker
+ * coordinates if intersection is suspiciously close to the point
+ * in order to eliminate self-shadowing.
+ *
+ * Ideally we need to solve this in Woop intersection code but
+ * it's quite tricky.
+ */
+ if(UNLIKELY(abs_det > 100000.0f && t < 1e-3f)) {
+ const float3 Ng = cross(A - B, C - A);
+ const float pleucker_den = dot(Ng, dir);
+ const float pleucker_T = dot(A, Ng);
+ if(UNLIKELY(pleucker_T * pleucker_den < 0.0f)) {
+ return false;
+ }
+ }
+#endif
+
isect->prim = triAddr;
isect->object = object;
isect->type = PRIMITIVE_TRIANGLE;
isect->u = U * inv_det;
isect->v = V * inv_det;
- isect->t = T * inv_det;
+ isect->t = t;
return true;
}
return false;