Apakah ada algoritma 'paling efisien' yang dikenal untuk deteksi tabrakan AABB vs Ray?
Saya baru-baru ini sengaja menemukan algoritma tabrakan Avo AABB vs Sphere Arvo, dan saya bertanya-tanya apakah ada algoritma yang sama pentingnya untuk ini.
Satu harus memiliki syarat untuk algoritma ini adalah bahwa saya harus memiliki opsi untuk menanyakan hasil untuk jarak dari asal sinar ke titik tumbukan. Setelah mengatakan ini, jika ada yang lain, algoritma lebih cepat yang tidak mengembalikan jarak, maka selain memposting yang melakukannya, juga memposting algoritma itu akan sangat membantu.
Harap sebutkan juga apa argumen pengembalian fungsi, dan bagaimana Anda menggunakannya untuk mengembalikan jarak atau kasus 'tanpa tabrakan'. Misalnya, apakah ia memiliki parameter keluar untuk jarak serta nilai pengembalian bool? atau apakah itu hanya mengembalikan pelampung dengan jarak, vs nilai -1 tanpa tabrakan?
(Bagi yang tidak tahu: AABB = Axis Aligned Bounding Box)
sumber
Jawaban:
Andrew Woo, yang bersama dengan John Amanatides mengembangkan algoritma raymarching (DDA) yang digunakan di mana-mana dalam raytracer, menulis "Fast Ray-Box Intersection" (sumber alternatif di sini ) yang diterbitkan dalam Graphics Gems, 1990, hlm. 395-396. Alih-alih dibangun khusus untuk integrasi melalui kisi (mis. Volume voxel) sebagaimana DDA (lihat jawaban zacharmarz), algoritme ini secara khusus cocok untuk dunia yang tidak terbagi secara merata, seperti dunia polyhedra khas Anda yang ditemukan di sebagian besar 3D pertandingan.
Pendekatan ini memberikan dukungan untuk 3D, dan secara opsional melakukan pengaburan backface. Algoritma ini berasal dari prinsip-prinsip integrasi yang sama yang digunakan dalam DDA, sehingga sangat cepat. Lebih detail dapat ditemukan dalam volume Permata Grafis asli (1990).
Banyak pendekatan lain khusus untuk Ray-AABB dapat ditemukan di realtimerendering.com .
EDIT: Alternatif, pendekatan tanpa cabang - yang diinginkan pada GPU & CPU - dapat ditemukan di sini .
sumber
Apa yang saya gunakan sebelumnya di raytracer saya:
Jika ini mengembalikan true, itu berpotongan, jika itu mengembalikan false, itu tidak berpotongan.
Jika Anda menggunakan sinar yang sama berkali-kali, Anda dapat melakukan precompute
dirfrac
(hanya pembagian di seluruh tes persimpangan). Dan kemudian sangat cepat. Dan Anda juga memiliki panjang sinar sampai persimpangan (disimpan dit
).sumber
Tidak ada yang menggambarkan algoritme di sini, tetapi algoritme Graphics Gems sederhana:
Dengan menggunakan vektor arah ray Anda, tentukan 3 dari 6 pesawat kandidat mana yang akan dipukul pertama . Jika vektor arah sinar (yang tidak dinormalkan) Anda adalah (-1, 1, -1), maka 3 bidang yang mungkin terkena adalah + x, -y, dan + z.
Dari 3 pesawat kandidat, temukan nilai-t untuk persimpangan untuk masing-masing. Terima pesawat yang mendapat nilai t terbesar sebagai pesawat yang tertabrak, dan periksa bahwa klik itu ada di dalam kotak . Diagram dalam teks memperjelas ini:
Implementasi saya:
sumber
Ini adalah persimpangan 3D ray / AABox yang pernah saya gunakan:
sumber
tnear
dantfar
?Ini adalah versi yang dioptimalkan dari yang saya gunakan untuk GPU:
sumber
Satu hal yang mungkin ingin Anda selidiki adalah meraster bagian depan dan belakang kotak pembatas Anda dalam dua buffer terpisah. Render nilai x, y, z sebagai rgb (ini bekerja paling baik untuk kotak pembatas dengan satu sudut di (0,0,0) dan sebaliknya di (1,1,1).
Jelas, ini memiliki penggunaan terbatas tetapi saya merasa hebat untuk merender volume sederhana.
Untuk lebih detail dan kode:
http://www.daimi.au.dk/~trier/?page_id=98
sumber
Inilah kode Line vs AABB yang telah saya gunakan:
sumber
Ini sepertinya mirip dengan kode yang diposting oleh zacharmarz.
Saya mendapatkan kode ini dari buku 'Deteksi Tabrakan Real-Time' oleh Christer Ericson di bawah bagian '5.3.3 Intersecting Ray atau Segment Against Box'
sumber
Saya terkejut melihat bahwa tidak ada yang menyebutkan metode slab tanpa cabang oleh Tavian
Penjelasan lengkap: https://tavianator.com/fast-branchless-raybounding-box-intersections/
sumber
Saya telah menambahkan jawaban @zacharmarz untuk menangani ketika asal berkas ada di dalam AABB. Dalam hal ini tmin akan negatif dan di belakang sinar sehingga tmax adalah persimpangan pertama antara sinar dan AABB.
sumber