From 4c1514bb3a606e0473fa2a8f723e4150566903f4 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 12 Jul 2021 09:25:07 -0600 Subject: [PATCH] Fix divide by zero in CanvasRayTracer The divide by zero happened when mapping a surface to a depth buffer. Some rays terminated at the origin, which is a singularity in the project matrix. This might be indicative of a larger problem. Rays really shouldn't terminate before the near plane. --- vtkm/rendering/CanvasRayTracer.cxx | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/vtkm/rendering/CanvasRayTracer.cxx b/vtkm/rendering/CanvasRayTracer.cxx index cf5fbda78..50a25e00c 100644 --- a/vtkm/rendering/CanvasRayTracer.cxx +++ b/vtkm/rendering/CanvasRayTracer.cxx @@ -59,15 +59,25 @@ public: point[2] = static_cast(intersection[2]); point[3] = 1.f; - vtkm::Vec4f_32 newpoint; - newpoint = vtkm::MatrixMultiply(this->ViewProjMat, point); - newpoint[0] = newpoint[0] / newpoint[3]; - newpoint[1] = newpoint[1] / newpoint[3]; - newpoint[2] = newpoint[2] / newpoint[3]; + vtkm::Float32 depth; + { + vtkm::Vec4f_32 newpoint; + newpoint = vtkm::MatrixMultiply(this->ViewProjMat, point); + if (newpoint[3] > 0) + { + depth = 0.5f * (newpoint[2] / newpoint[3]) + 0.5f; + } + else + { + // This condition can happen when the ray is at the origin (inDepth = 0), which is a + // singularity in the projection matrix. I'm not sure this is the right think to do since + // it looks like depth is supposed to be between 0 and 1. It seems wrong that you would + // ever get a ray in front of the near plane, so the "right" solution may be to fix this + // elsewhere. + depth = vtkm::NegativeInfinity32(); + } + } - vtkm::Float32 depth = newpoint[2]; - - depth = 0.5f * (depth) + 0.5f; vtkm::Vec4f_32 color; color[0] = static_cast(colorBufferIn.Get(index * 4 + 0)); color[1] = static_cast(colorBufferIn.Get(index * 4 + 1));