Gibt es einen bekannten, 'effizientesten' Algorithmus für die Erkennung von AABB-Ray-Kollisionen?
Kürzlich bin ich über den Kollisionsalgorithmus AABB vs Sphere von Arvo gestolpert, und ich frage mich, ob es dafür einen ähnlich bemerkenswerten Algorithmus gibt.
Eine Bedingung für diesen Algorithmus muss sein, dass ich die Option haben muss, das Ergebnis für die Entfernung vom Ursprung des Strahls zum Kollisionspunkt abzufragen. Wenn es jedoch einen anderen, schnelleren Algorithmus gibt, der keine Distanz zurückgibt, dann wäre es in der Tat sehr hilfreich, zusätzlich zu einem, der dies tut, auch diesen Algorithmus zu veröffentlichen.
Bitte geben Sie auch an, was das Rückgabeargument der Funktion ist und wie Sie es verwenden, um die Distanz oder einen Fall ohne Kollision zurückzugeben. Hat es beispielsweise einen out-Parameter für die Entfernung sowie einen bool-Rückgabewert? oder gibt es einfach einen float mit der entfernung gegen einen wert von -1 für keine kollision zurück?
(Für diejenigen, die nicht wissen: AABB = Axis Aligned Bounding Box)
quelle
Antworten:
Andrew Woo, der zusammen mit John Amanatides den in Raytracern allgegenwärtig verwendeten Raymarching-Algorithmus (DDA) entwickelte, schrieb "Fast Ray-Box Intersection" (alternative Quelle hier ), der in Graphics Gems, 1990, S. 395-396 veröffentlicht wurde. Dieser Algorithmus ist nicht speziell für die Integration durch ein Gitter (z. B. ein Voxelvolumen) wie DDA (siehe zacharmarz 'Antwort) entwickelt worden, sondern eignet sich speziell für Welten, die nicht gleichmäßig unterteilt sind, wie z. B. Ihre typische Polyederwelt in den meisten 3D-Umgebungen Spiele.
Der Ansatz bietet Unterstützung für 3D und führt optional das Backface-Culling durch. Der Algorithmus basiert auf den gleichen Integrationsprinzipien wie in DDAs und ist daher sehr schnell. Weitere Details finden Sie im Original Graphics Gems Band (1990).
Viele andere Ansätze speziell für Ray-AABB finden Sie auf realtimerendering.com .
BEARBEITEN: Ein alternativer, verzweigungsloser Ansatz - der sowohl für die GPU als auch für die CPU wünschenswert wäre - kann hier gefunden werden .
quelle
Was ich früher in meinem Raytracer verwendet habe:
Wenn dies wahr ist, schneidet es sich, wenn es falsch ist, schneidet es sich nicht.
Wenn Sie denselben Strahl mehrmals verwenden, können Sie vorberechnen
dirfrac
(nur Teilung im gesamten Schnittpunkttest). Und dann geht es richtig schnell. Und Sie haben auch Länge des Strahls bis zur Kreuzung (gespeichert int
).quelle
Niemand hat den Algorithmus hier beschrieben, aber der Graphics Gems-Algorithmus ist einfach:
Bestimmen Sie anhand des Richtungsvektors Ihres Strahls, welche 3 der 6 möglichen Flugzeuge zuerst getroffen werden . Wenn Ihr (nicht normalisierter) Strahlrichtungsvektor (-1, 1, -1) ist, sind die 3 Ebenen, die getroffen werden können, + x, -y und + z.
Finden Sie von den 3 Kandidatenebenen für jede den t-Wert für den Schnittpunkt. Akzeptieren Sie die Ebene, die den größten t- Wert erhält , als die Ebene, die getroffen wurde, und überprüfen Sie, ob der Treffer innerhalb des Felds liegt . Das Diagramm im Text macht dies deutlich:
Meine Implementierung:
quelle
Dies ist meine 3D-Ray / AABox-Kreuzung, die ich verwendet habe:
quelle
tnear
undtfar
?Hier ist eine optimierte Version der oben genannten, die ich für die GPU verwende:
quelle
Möglicherweise möchten Sie die Vorder- und Rückseite Ihres Begrenzungsrahmens in zwei separaten Puffern rastern. Rendern Sie die x, y, z-Werte als rgb (dies funktioniert am besten für einen Begrenzungsrahmen mit einer Ecke bei (0,0,0) und der gegenüberliegenden bei (1,1,1).
Natürlich hat dies nur eine begrenzte Verwendung, aber ich fand es großartig, um einfache Volumes zu rendern.
Für mehr Details und Code:
http://www.daimi.au.dk/~trier/?page_id=98
quelle
Hier ist der Code von Line vs AABB, den ich verwendet habe:
quelle
Dies scheint dem von zacharmarz geposteten Code zu ähneln.
Ich habe diesen Code aus dem Buch 'Real-Time Collision Detection' von Christer Ericson im Abschnitt '5.3.3 Ray oder Segment gegen Box schneiden' erhalten.
quelle
Ich bin überrascht zu sehen, dass niemand die astlose Plattenmethode von Tavian erwähnt hat
Vollständige Erklärung: https://tavianator.com/fast-branchless-raybounding-box-intersections/
quelle
Ich habe @zacharmarz Antwort hinzugefügt, um zu behandeln, wann der Strahlursprung innerhalb des AABB ist. In diesem Fall ist tmin negativ und liegt hinter dem Strahl, sodass tmax der erste Schnittpunkt zwischen dem Strahl und AABB ist.
quelle