Search code examples
c++mathgraphicsopenclraytracing

problem with ray quad intersection code (looks like tearing)


Hi I am implementing monte carlo path tracing and I have it working fine but looks like there is some issue with intersection code . Following is image

enter image description here

If you see in red in left corner there seems to be showing background color.

following is

float intersectQuad(Ray r, float3 p1, float3 p2, float3 p3, float3 p4, 
float3* outNormal)
{
 const float3 x1 = p2 - p1;
 const float3 x2 = p4 - p1;
 const float3 n = (cross(x2, x1));
 const float denom = dot(n, r.dir); 

 if (denom < 0.00000000001f) return 0.0f;

 const float3 p0l0 = (p1 - r.origin); 
 const float t = dot(p0l0, n) / denom; 

 if( t < 0.000000000001f ) return 0.0f;

 const float3 hitPoint = r.origin + r.dir * t;

 const float3 V1 = normalize(p2 - p1);
 const float3 V2 = normalize(p3 - p2);
 const float3 V3 = normalize(p4 - p3);
 const float3 V4 = normalize(p1 - p4);
 const float3 V5 = normalize(hitPoint - p1);
 const float3 V6 = normalize(hitPoint - p2);
 const float3 V7 = normalize(hitPoint - p3);
 const float3 V8 = normalize(hitPoint - p4);

 if (dot(V1,V5) < 0.0f) return 0.0f;
 if (dot(V2,V6) < 0.0f) return 0.0f;
 if (dot(V3,V7) < 0.0f) return 0.0f;
 if (dot(V4,V8) < 0.0f) return 0.0f;

 *outNormal = n;

 return t;
}

The way I am calling code is

const float inf = 1e20f;
float t = inf;
float hitDistance = 0.0f;
for(int j = 0; j < numberOfQuads; j+=16)
{
 //v1 , v2 , v3 , v4 are 4 vertices of quad in counter clockwise order
 hitDistance = intersectQuad(*ray, v1, v2, v3 ,v4, &n);

 if(hitDistance != 0.0f && hitDistance < t )
 {
   t = hitDistance; 
   colorIndex = k;
   normal = n;
 }
}
return t < inf;

I am not sure where I am making mistake.


Solution

  • Your rays are missing both quads; it is a "crack". Any inconsistency or numerical inaccuracy in hit testing code can cause "cracks" or "seams" where the ray hits neither poly when it should hit exactly one. It is a common problem, but solvable. It is also a problem to be avoided in rasterization, not just ray tracing. Keep in mind that floats and doubles are not infinitely precise. Always make sure the calculation for an edge on one poly is the same for the same edge on the adjacent poly. In other words, are both of your quads in clockwise or counter-clockwise order?

    Here's a nice paper: jcgt.org/published/0002/01/05/paper.pdf