c++ opengl 3d glsl raytracing

c++ - ¿Qué está causando los artefactos en mi raytracer?



opengl 3d (1)

Así que resulta que no fue el código que había publicado lo que causó el problema. Gracias a un poco de ayuda en el comentario, pude encontrar que era este código cuando determiné el objeto más cercano a la cámara:

float nearest_t = FAR_CLIP; int nearest_index = 0; for (int j=0; j<NumObjects; j++) { float t = FAR_CLIP; t = FindRayObjectIntersection(r, objects[j]); if (t < nearest_t && t > EPSILON && t < FAR_CLIP) { nearest_t = t; nearest_index = j; } }

Al determinar t, a veces los triángulos estaban tan juntos que t < nearest_t tenía un resultado casi probabilístico, ya que las intersecciones eran aproximadamente la misma distancia de la cámara.

Mi solución inicial fue cambiar la sentencia if interna a:

if (t < nearest_t-EPSILON && t > EPSILON && t < FAR_CLIP)

Esto asegura que si dos intersecciones están muy juntas, siempre elegirá el primer objeto a mostrar (a menos que el segundo objeto esté más cerca al menos EPSILON ). Aquí hay una imagen resultante (con los reflejos desactivados):

Ahora todavía había algunos artefactos pequeños, así que estaba claro que todavía había un pequeño problema. Así que después de una discusión en los comentarios, a @Soonts se le ocurrió la idea de mezclar los colores de los triángulos. Esto me lleva a tener que cambiar el código anterior para seguir la distancia a ambos triángulos:

if (t > EPSILON && t < FAR_CLIP && abs(nearest_t - t) < EPSILON) { nearest_index2 = nearest_index; nearest_t2 = nearest_t; } if (t < nearest_t+EPSILON && t > EPSILON && t < FAR_CLIP) { nearest_t = t; nearest_index = j; }

También he añadido este código de mezcla de colores:

OverallColor = mix(c1, c2, 0.5f * abs(T1 - T2) / EPSILON);

Después de estos dos pasos, y honestamente creo que este efecto se debió más al cambio lógico que al cambio de combinación, obtuve este resultado:

Espero que a otros les resulte útil esta solución, o al menos que genere algunas ideas para resolver sus propios problemas. Como ejemplo final, aquí está el hermoso resultado con reflejos, sombras más suaves y algunos efectos anti-alias activados:

Feliz raytracing!

EDIT : ahora he resuelto el problema; Puedes ver mi solución en las respuestas.

Estoy en el proceso de escribir un trazador de rayos en tiempo real utilizando OpenGL (en un GLSL Compute Shader), y me he encontrado con un pequeño problema con algunas de mis intersecciones de línea-triángulo (o al menos, creo que son los culpables) . Aquí hay una foto de lo que está pasando:

Como puede ver, algunos píxeles están siendo coloreados de negro en la intersección de dos triángulos cerca de la parte superior de la imagen. Probablemente tenga algo que ver con la forma en que manejo los flotadores o algo así, y he intentado buscar una solución en línea pero no puedo encontrar situaciones similares. Tal vez hay una palabra clave importante que me falta?

De todos modos, la pieza de código importante es esta:

#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; }

Probé varios valores para EPSILON , probé variaciones con +/- para los valores EPSILON , pero fue en vano. Además, al cambiar el 1.0f+EPSILON a un 1.0-EPSILON obtiene una línea negra estable en todo el camino.

También para aclarar, definitivamente NO hay una brecha entre los dos triángulos. Están muy apretados (y también he intentado extenderlos para que se crucen, pero todavía tengo los mismos puntos negros).

Curiosamente, la intersección del fondo no muestra signos de este fenómeno.

Última nota: si se necesita más de mi código, solo pregunte e intentaré aislar un poco más de código (o tal vez solo un enlace a todo el sombreador).

ACTUALIZACIÓN : Se señaló que los ''artefactos negros'' son de hecho marrones. Así que he cavado un poco más profundo y desactivé todas las reflexiones, y obtuve este resultado:

El color marrón proviene realmente del material de cobre en la parte superior, pero lo más importante es que tengo una idea de cuál es la causa del problema, pero no estoy más cerca de resolverlo.

Parece que cuando los rayos se disparan, debido a imperfecciones muy leves en la aritmética flotante, algunos rayos se intersecan con el triángulo superior, y algunos se intersecan con el inferior.

Así que supongo que ahora la pregunta se reduce a esto: ¿cómo puedo tener algún tipo de coherencia para decidir qué triángulo debe ser golpeado en casos como este?