2017-08-18 14 views
0

J'essaye de faire mon propre raytracer dans Javascript. Jusqu'à présent, les sphères fonctionnent très bien. Je veux maintenant étendre les capacités pour inclure des triangles, et de là je peux aller aux carrés, aux cubes et au-delà. Le code j'ai pour trouver des intersections avec des triangles est comme suitL'intersection de triangles dans raytracer ne fonctionne pas

function triangleIntersection(t, r) { 
var norm = triangleNormal(t); 
var dist = triangleDistance(t); 
var a = Vector.dotProduct(r.vector, norm); 

if (a === 0) { 
    return -1; 
} else { 
    var b = Vector.dotProduct(norm, Vector.add(r.point, Vector.negative(Vector.multiply(norm, dist)))); 
    var d = -1 * b/a; 

    var qx = Vector.scale(r.vector, d).x + r.point.x; 
    var qy = Vector.scale(r.vector, d).y + r.point.y; 
    var qz = Vector.scale(r.vector, d).z + r.point.z; 

    var q = new Vector(qx, qy, qz); 

    var ca = Vector.subtract(t.points[2], t.points[0]); 
    var qa = Vector.subtract(q, t.points[0]); 
    var t1 = Vector.dotProduct(Vector.crossProduct(ca, qa), norm); 

    var bc = Vector.subtract(t.points[1], t.points[2]); 
    var qc = Vector.subtract(q, t.points[2]); 
    var t2 = Vector.dotProduct(Vector.crossProduct(bc, qc), norm); 

    var ab = Vector.subtract(t.points[0], t.points[1]); 
    var qb = Vector.subtract(q, t.points[1]); 
    var t3 = Vector.dotProduct(Vector.crossProduct(ab, qb), norm); 

    if ((t1 >= 0) && (t2 >= 0) && (t3 >= 0)) { 
     return 1 * b/a; 
    } else { 
     return -1; 
    } 
} 

}

objets triangulaires ont une matrice de points (points[]) et le point 0 est le point A, le point 1 est le point B et le point 2 est le point C. Le paramètre t est l'un de ces triangles. Le paramètre r est un objet rayon, avec les propriétés point qui est l'origine et vector, qui est la direction. J'ai aussi ces fonctions pour trouver la normale et la distance d'un triangle.

function triangleNormal(s) { 
var ca = Vector.subtract(s.points[2], s.points[0]); 
var ba = Vector.subtract(s.points[1], s.points[0]); 
var norm = Vector.unitVector(Vector.crossProduct(ca, ba)); 

return norm; 
} 

function triangleDistance(t) { 
    return Vector.dotProduct(triangleNormal(t, 0), t.points[0]); 
} 

Lorsque je rends ma scène, le triangle que j'utilise dans ma scène est de couleur rouge. Peu importe jusqu'où je remonte mon appareil photo, le triangle remplit toute la scène en rouge. Je ne sais pas pourquoi cela arrive.

+1

Pourquoi ne pas essayer l'algorithme * Moller-Trumbore *? https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm – meowgoesthedog

+0

@meowgoesthedog Bon, je vais essayer ça. Thx tellement :) – Adam

+0

@ meowgoesthedog Ugh la même erreur. Je suppose que je vais devoir recommencer à zéro ... – Adam

Répondre

0

Une erreur importante dans votre code d'intersection plan est cette opération de comparaison:

a === 0

Il y a deux choses mal avec elle:

  1. Pour raytracing que vous voulez le rayon de frapper plans devant de sa source, pas derrière lui, donc vous avez besoin a < 0.

  2. Même si vous avez veulent que le rayon de frapper les avions derrière, vous devez jamais faire des opérations d'égalité entre les valeurs à virgule flottante, parce que les calculs à virgule flottante sont pressera pas. (Vous devez faire quelque chose comme abs(a) < 1e-6f ou une petite valeur)

+0

Informations très utiles. va essayer et accepter si fonctionne. :) Merci Monsieur – Adam