EDIT: я решил проблему; вы можете увидеть мое решение в ответах.
Я занимаюсь написанием raytracer в реальном времени с использованием OpenGL (в GLSL Compute Shader), и у меня возникла небольшая проблема с некоторыми из моих пересечений линий треугольника (или, по крайней мере, я считаю, что они виновник). Вот картина того, что происходит:
Как вы можете видеть, некоторые пиксели окрашиваются в черный цвет на пересечении двух треугольников вблизи верхней части изображения. Вероятно, это связано с тем, как я обрабатываю поплавки или что-то в этом роде, и я попытался найти решение в Интернете, но не могу найти похожие ситуации. Возможно, есть важное ключевое слово, которое мне не хватает?
В любом случае важной частью кода является этот:
#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;
}
Я пробовал различные значения для EPSILON
, пробовал варианты с +/- для значений EPSILON
, но безрезультатно. Кроме того, изменение 1.0f+EPSILON
на a 1.0-EPSILON
дает устойчивую черную линию на всем пути.
Также, чтобы уточнить, определенно НЕ является пробелом между двумя треугольниками. Они плотно упакованы (и я также попытался расширить их, чтобы они пересекались, но я все равно получаю одни и те же черные точки).
Любопытно, что нижнее пересечение не показывает никаких признаков этого явления.
Последнее примечание: если требуется больше моего кода, просто спросите, и я попытаюсь выделить еще один код (или, возможно, просто ссылку на весь шейдер).
ОБНОВЛЕНИЕ. Было указано, что "черные артефакты" на самом деле коричневые. Поэтому я углубился и выключил все отражения, и получил этот результат:
Коричневый цвет на самом деле происходит только из медного материала сверху, но, что более важно, я думаю, что у меня есть идея, в чем причина проблемы, но я не ближе к ее решению.
Похоже, что когда лучи испускаются из-за очень слабых несовершенств в плавающей арифметике, некоторые лучи пересекают верхний треугольник, а некоторые пересекают нижнюю часть.
Итак, я полагаю, что теперь вопрос сводится к следующему: как я могу иметь некоторую согласованность при решении вопроса о том, какой треугольник следует использовать в таких случаях?