Ich schreibe einen Raytracer in Java, und ich war in der Lage, die Verfolgung von Kugeln zu verfolgen, aber ich glaube, ich habe etwas falsch damit, wie ich Dreiecke zeichne.Raytracing-Dreiecke
Hier ist der grundlegende Algorithmus, wie ich es verstehe:
- zuerst fest, ob der Strahl auch die schneidet Ebene, dass das Dreieck ist.
- Alle Punkte so einschneiden, dass sie sich in der gleichen Ebene wie das Dreieck befinden (als Beispiel für die Ebene
xy
). - Bestimmen Sie, ob der potenzielle Schnittpunkt innerhalb oder außerhalb des Dreiecks liegt, basierend auf der Anzahl der Polygonkanten, die Sie kreuzen, wenn Sie einen Strahl in einer beliebigen Richtung entlang der neuen Ebene senden.
Nun, hier ist meine Implementierung dass (insbesondere der erste Punkt):
public Vector getIntersectionVector(Ray ray)
{
Vector planeIntersectionVector = getPlaneIntersectionVector(ray, getPlaneNormal());
if (planeIntersectionVector != null)
{
if (isIntersectionVectorInsideTriangle(planeIntersectionVector))
{
return planeIntersectionVector;
}
else
{
return null;
}
}
else
{
return null;
}
}
Wo getPlaceIntersectionVector()
ist:
private Vector getPlaneIntersectionVector(Ray ray, Vector planeNormal)
{
double vd = planeNormal.dotProduct(ray.getDirection());
//(p_n \dot r_d) == 0, parallel. (p_n \dot r_d) > 0 Plane normal pointing away from ray.
if (vd >= 0)
{
return null;
}
double distance = planeNormal.distance(0d, 0d, 0d);
double vo = -(planeNormal.dotProduct(ray.getOrigin()) + distance);
double intersectionDistance = vo/vd;
//intersectionDistance <= 0 means the "intersection" is behind the ray, so not a real intersection
return (intersectionDistance <= 0) ? null : ray.getLocation(intersectionDistance);
}
die im Grunde diese nachzuahmen versucht:
Wo t
der Abstand entlang des Strahls ist, dass der Punkt-Hits, r o der Ursprung des Strahls ist, r d ist die Richtung des Strahls, p n zur Ebene verweist Normale des Dreiecks/Ebene, und d
ist der Abstand von der Ebene, die das Dreieck auf dem Ursprung ist (0,0,0)
Mache ich das falsch? Wenn ich den Strahl vom ersten Pixel im Bild (0,0)
aussende, sehe ich, dass die intersectionDistance
(oder t
) fast 1100
ist, was mir intuitiv intuitiv falsch erscheint. Ich würde denken, dass der Schnittpunkt viel näher wäre.
Hier sind die relevanten Daten: Ray Herkunft (0,0,1)
, Ray Direction ist ungefähr (0.000917, -0.4689, -0.8833)
.
Dreieck hat Ecken wie (-0.2, 0.1, 0.1)
, (-0.2, -0.5, 0.2)
, (-0.2, 0.1, -0.3)
, die das Flugzeug normal (-1, 0, 0)
macht.
Nach meinem Code, der Ray schneidet das Flugzeug 1090
Entfernung entfernt, die wie ich schon erwähnt, scheint mir falsch. Die Szene ist in jeder Richtung nur -1,0 bis 1,0, was bedeutet, dass die Kreuzung sehr weit entfernt ist.
Mache ich die Flugzeugkreuzung falsch?
Bitte lassen Sie mich wissen, wo Punkte zu klären, und wenn Sie weitere Informationen benötigen.
Angenommen, ich habe die Ebene von der Normalen des Dreiecks definiert. Wie würde ich in diesem Fall die Entfernung vom Flugzeug zum Ursprung bekommen? Von [dieser Antwort] (http://math.stackexchange.com/a/651535/375627) dachte ich, dass es nur das Punktprodukt zwischen der Normalen und einem Vektor in der Ebene ist (in diesem Fall einer der Eckpunkte)), aber das scheint falsch zu sein, denn jetzt ist die Kreuzung etwa 218. –
"Ich dachte, dass es nur das Skalarprodukt zwischen der Normalen und einem Vektor in der Ebene war" - das sollte stimmen. Überprüfen Sie, ob der normale Vektor Ihres Flugzeugs normalisiert ist – samgak
Sind Sie wirklich sicher, dass das Ergebnis falsch ist? Der Schnittpunktabstand ist * in Richtung der Strahlrichtung *, nicht der Abstand des nächsten Punktes in der Ebene vom Strahlenursprung. Da dein Strahl fast senkrecht zur Normalen der Ebene ist (er hat nur einen Wert von 0,000917 in Richtung der Flächennormalen), musst du relativ weit in diese Richtung fahren, bevor du dich überschneidest. – samgak