EDIT: I have now solved the problem; you can see my solution in the answers.
I'm in the process of writing a realtime raytracer using OpenGL (in a GLSL Compute Shader), and I've run into a slight problem with some of my line-triangle intersections (or at least, I believe they are the culprit). Here's a picture of what's happening:
As you can see some pixels are being coloured black at the intersection of two triangles near the top of the image. It's probably got something to do with the way I'm handling floats or something, and I've tried searching for a solution online but can't find similar situations. Perhaps there's an important keyword I'm missing?
Anyways, the important piece of code is this one:
#define EPSILON 0.001f
#define FAR_CLIP 10000.0f
float FindRayTriangleIntersection(Ray r, Triangle p)
{
// Based on Moller-Trumbone paper
vec3 E1 = p.v1 - p.v0;
vec3 E2 = p.v2 - p.v0;
vec3 T = r.origin - p.v0;
vec3 D = r.dir;
vec3 P = cross(D, E2);
vec3 Q = cross(T, E1);
float f = 1.0f / dot(P, E1);
float t = f * dot(Q, E2);
float u = f * dot(P, T);
float v = f * dot(Q, D);
if (u > -EPSILON && v > -EPSILON && u+v < 1.0f+EPSILON) return t;
else return FAR_CLIP;
}
I've tried various values for EPSILON
, tried variations with +/- for the EPSILON
values, but to no avail. Also, changing the 1.0f+EPSILON
to a 1.0-EPSILON
yields a steady black line the whole way across.
Also to clarify, there definitely is NOT a gap between the two triangles. They are tightly packed (and I have also tried extending them so they intersect, but I still get the same black dots).
Curiously enough, the bottom intersection shows no sign of this phenomenon.
Last note: if more of my code is needed just ask and I'll try to isolate some more code (or maybe just link to the entire shader).
UPDATE: It was pointed out that the 'black artifacts' are in fact brown. So I've dug a bit deeper and turned off all reflections, and got this result:
The brown colour is actually coming from just the copper material on the top, but more importantly I think I have an idea what the cause of the problem is, but I'm no closer to solving it.
It seems that when the rays get fired out, due to very slight imperfections in the floating arithmetic, some rays intersect the top triangle, and some intersect the bottom.
So I suppose now the question reduces to this: how can I have some sort of consistency in deciding which triangle should be hit in cases like this?