Three.js: Permintaan fitur: Tingkatkan kinerja deteksi tabrakan raycaster melalui pohon pencarian spasial

Dibuat pada 11 Des 2017  ·  36Komentar  ·  Sumber: mrdoob/three.js

Saya telah membangun aplikasi VR yang mirip dengan WebVR-Vive-Dragging yang memungkinkan untuk berinteraksi dengan banyak objek 3d menggunakan pengontrol VR. Ini berarti bahwa pengguna dapat mengambil objek dengan pengontrol VR dan dapat memindahkan atau menskalakannya.

Masalah : Ketika ada objek 3d yang kompleks dalam adegan, yaitu objek THREE.Mesh yang memiliki geometri dengan jumlah simpul yang sangat besar, maka raycasting selama deteksi tabrakan menjadi sangat lambat. Oleh karena itu, masalahnya adalah kompleksitas geometri satu objek.

Ada struktur data pohon untuk pencarian spasial cepat, seperti Octree atau R-Tree . Saya telah menemukan threeocttree yang memungkinkan untuk membagi geometri menjadi potongan yang lebih kecil tetapi tampaknya agak ketinggalan zaman (Three.js r60).

Sejauh yang saya lihat, dalam metode THREE.Mesh objek raycast sudah ada beberapa optimasi kinerja (memeriksa kotak pembatas dan bola terlebih dahulu sebelum melakukan raycast yang sebenarnya). Mungkin masuk akal untuk memiliki tahap pemeriksaan lain menggunakan pohon pencarian spasial?! Bagaimana menurutmu?

Salam Hormat

Enhancement

Komentar yang paling membantu

Saya telah menyarankan indeks spasial untuk dimasukkan ke dalam threejs di masa lalu. Ada beberapa pekerjaan ke arah ini, dan contoh pohon okt yang ada adalah salah satunya. Pada akhirnya, saya pikir kurangnya minat dari komunitas inti sehubungan dengan memiliki fungsi ini sebagai warga negara kelas satu di tiga.

Saya akan dengan senang hati menyumbangkan kode BVH saya ke proyek, jika ada minat dan niat yang cukup untuk memasukkannya ke dalam distribusi utama (bukan contoh).
Kode saya berfokus pada 2 aspek:

  • adegan dinamis

    • masukkan cepat

    • penghapusan cepat

    • refitting (kemampuan node untuk berubah bentuk tanpa harus dimasukkan kembali)

  • kecepatan kueri

Saya memiliki 2 implementasi:

  • BinerBVH

    • sangat kompak, menggunakan ByteBuffer

    • campuran jenis UintX dan FloatX melalui DataView

    • bagus untuk serialisasi

    • dapat dikompresi menggunakan alat standar seperti perpustakaan lzma

    • kekal

    • kecepatan build sangat dioptimalkan

    • hanya berfungsi untuk BufferGeometry

    • optimasi SAH

    • pertanyaan sinar

  • BVH

    • Pohon objek, sebagai konsekuensinya jauh lebih besar daripada implementasi biner

    • yg mungkin berubah

    • penyisipan massal cepat

    • penyisipan item tunggal cepat

    • pemasangan kembali

    • implementasi traversal stack, rekursif dan stack-less (karakteristik kinerja berbeda)

    • optimasi SAH

    • Pertanyaan frustrasi

    • Pertanyaan Ray

Secara pribadi, saya tidak bisa hidup tanpa indeks spasial, ini adalah perbedaan antara kinerja n^2 dan log(n). Misalnya, dalam proyek saya saat ini, bagian berikut bergantung pada indeks spasial:

  • sistem dedaunan (pohon, bunga, semak dll)
  • semua penempatan objek (karakter dan rumah)
  • memetik (digunakan dalam interaksi, seperti klik mouse)

http://server1.lazy-kitty.com/komrade

medan memiliki poligon sekitar 1m, dan menempatkan ribuan pohon dan menjalankan ray-cast secara real-time di atasnya bukanlah hal yang mudah, terutama untuk perangkat kelas bawah.

Semua 36 komentar

Dengan risiko menyatakan yang sudah jelas, tetapi apakah Anda sudah mencoba versi threeocttree yang sudah ada di repo( example/js/Octree.js )?

Saya tidak memilih penggunaan terprogram pohon pencarian spasial di three.js . Overhead/kompleksitas dari algoritme semacam itu membuat peningkatan kinerja di banyak aplikasi menjadi lebih seimbang.

memeriksa kotak pembatas dan bola terlebih dahulu sebelum melakukan raycast yang sebenarnya

Ini masuk akal dan harus cukup. Jika pengguna membutuhkan lebih banyak kinerja dalam konteks kasus penggunaan yang lebih maju, mereka dapat menggunakan contoh yang disebutkan sebagai titik awal. Oktre mungkin merupakan pilihan yang baik. Tetapi saya belum pernah melihat solusi R-Tree dalam aplikasi 3D interaktif karena pendekatannya cukup canggih (algoritme melakukan data alih-alih mempartisi ruang).

Halo dan terima kasih atas balasan Anda,
@ Mugen87 Saya setuju bahwa banyak kasus penggunaan tidak memerlukan pencarian cepat seperti itu. Namun, memiliki mekanisme untuk berinteraksi dengan objek 3D (dan saya rasa itulah yang paling sering digunakan), langkah THREE.Raycaster dari mencentang kotak/bola terlebih dahulu (yang saya setujui sepenuhnya masuk akal ) di katakanlah waktu konstan untuk upaya waktu linier ketika melakukan raycast sebenarnya cukup besar. Saya bisa membayangkan semacam "pohon pencarian-per-geometri" alih-alih satu pohon pencarian global. Selama geometri tidak berubah (seringkali transformasi jauh lebih mungkin daripada perubahan geometri) pohon pencarian tidak perlu diperbarui.

Itu sebabnya saya berpikir, pengoptimalan semacam itu menggunakan pohon pencarian spasial bisa menjadi bagian yang lebih integral dari three.js . Tetapi saya juga mengerti bahwa ini menyebabkan kompleksitas dan overhead tambahan.

@moraxy saya akan melihat contoh versi. Saya hanya ingin tahu apakah fitur seperti itu masuk akal.

Terima kasih kembali dan salam

Mungkin pohon pencarian yang lebih sederhana dapat diintegrasikan ke dalam THREE.BufferGeometry . Misalnya panggilan ke computeBoundingBox juga bisa membangun semacam pohon pencarian read-only yang mereferensikan simpul yang sesuai. Karena THREE.BufferGeometry adalah

paling cocok untuk objek statis di mana Anda tidak perlu terlalu banyak memanipulasi geometri setelah membuat instance-nya

pohon pencarian ini tidak perlu diubah setelah inisialisasi. Ini akan mengurangi beberapa overhead untuk memperbarui/menghapus. Octree akan menjadi titik awal yang baik ( konsep serupa di BabylonJS ).

paling cocok untuk objek statis di mana Anda tidak perlu terlalu banyak memanipulasi geometri setelah membuat instance-nya

FWIW, saya tidak percaya itu pernyataan yang benar.

@WestLangley Kutipan dari dokumentasi THREE.BufferGeometry

TIGA.Dokumentasi BufferGeometry

Itu mungkin harus dihapus - dalam hal apa pun, saya tidak berpikir itu dimaksudkan sebagai pernyataan teknis apa pun, melainkan berarti lebih sulit bagi pengguna untuk memanipulasi geometri setelah dibuat.

Itu mungkin harus dihapus

Paling pasti.

Saya baru saja menerapkan metode yang lebih baik untuk raycasting di PlaneBufferGeometry. Saya menggunakan parameter jauh dan menemukan posisi indeks pertama dan terakhir. Ini berfungsi di planebuffer karena array indeks dalam urutan x/y. Setelah berada di luar kotak pembatas x/y, semua tumbukan harus berada di luar jarak jauh. Apakah ada keinginan untuk melakukan ini di suatu tempat? Implementasi saat ini khusus untuk kasus penggunaan saya, tetapi saya akan bersedia untuk mencoba dan membuatnya lebih umum jika diinginkan. Saya dapat mengurangi kinerja raycasting saya secara signifikan pada planeBuffer besar (2,5 detik hingga 10 ms)

@kpetrow Saya pikir contoh octree three.js sudah memadai. Anda tentu saja bebas untuk membagikan kode Anda di GitHub jika Anda merasa itu berguna bagi orang lain.

Saya telah menyarankan indeks spasial untuk dimasukkan ke dalam threejs di masa lalu. Ada beberapa pekerjaan ke arah ini, dan contoh pohon okt yang ada adalah salah satunya. Pada akhirnya, saya pikir kurangnya minat dari komunitas inti sehubungan dengan memiliki fungsi ini sebagai warga negara kelas satu di tiga.

Saya akan dengan senang hati menyumbangkan kode BVH saya ke proyek, jika ada minat dan niat yang cukup untuk memasukkannya ke dalam distribusi utama (bukan contoh).
Kode saya berfokus pada 2 aspek:

  • adegan dinamis

    • masukkan cepat

    • penghapusan cepat

    • refitting (kemampuan node untuk berubah bentuk tanpa harus dimasukkan kembali)

  • kecepatan kueri

Saya memiliki 2 implementasi:

  • BinerBVH

    • sangat kompak, menggunakan ByteBuffer

    • campuran jenis UintX dan FloatX melalui DataView

    • bagus untuk serialisasi

    • dapat dikompresi menggunakan alat standar seperti perpustakaan lzma

    • kekal

    • kecepatan build sangat dioptimalkan

    • hanya berfungsi untuk BufferGeometry

    • optimasi SAH

    • pertanyaan sinar

  • BVH

    • Pohon objek, sebagai konsekuensinya jauh lebih besar daripada implementasi biner

    • yg mungkin berubah

    • penyisipan massal cepat

    • penyisipan item tunggal cepat

    • pemasangan kembali

    • implementasi traversal stack, rekursif dan stack-less (karakteristik kinerja berbeda)

    • optimasi SAH

    • Pertanyaan frustrasi

    • Pertanyaan Ray

Secara pribadi, saya tidak bisa hidup tanpa indeks spasial, ini adalah perbedaan antara kinerja n^2 dan log(n). Misalnya, dalam proyek saya saat ini, bagian berikut bergantung pada indeks spasial:

  • sistem dedaunan (pohon, bunga, semak dll)
  • semua penempatan objek (karakter dan rumah)
  • memetik (digunakan dalam interaksi, seperti klik mouse)

http://server1.lazy-kitty.com/komrade

medan memiliki poligon sekitar 1m, dan menempatkan ribuan pohon dan menjalankan ray-cast secara real-time di atasnya bukanlah hal yang mudah, terutama untuk perangkat kelas bawah.

Saya ingin melihat apa pun yang membuat raycast dioptimalkan. Apakah ada ruang untuk pengoptimalan tanpa menambah kerumitan? Octree membutuhkan semua perpustakaan baru, dengan semua penambahan dan pembaruan baru, dll.

Satu hal yang saya perhatikan adalah bahwa setelah geometri dikonversi ke array buffer yang diindeks, ia tidak lagi menggunakan properti geometri asli dengan cerdas. Seperti disebutkan di atas geometri penyangga bidang dapat dioptimalkan secara super dengan mengetahui bahwa arrayBuffer berasal dari PlaneGeometry. Mungkin menimpa metode MESH.raycast ( raycaster, intersects ) berdasarkan tipe geometri?

Pendekatan lain adalah menjadikan Raycaster sebagai plug-in terpisah -- seperti halnya kontrol interaktif dan loader. Kemudian, menambahkan raycaster berkinerja mirip dengan yang diusulkan @Usnul akan sangat bagus.

Saya menyukai gagasan memiliki Raycaster yang dapat dicolokkan, tetapi saya pikir ada sedikit kebingungan. Apa yang menurut saya berguna adalah indeks spasial, bukan Raycaster semata. Indeks spasial memungkinkan hal-hal seperti:

  • pemusnahan spasial (pikirkan pemusnahan frustum)
  • melakukan kueri visibilitas
  • membangun penyaji penelusuran jalur
  • penyortiran cepat (mengeksploitasi lokalitas data)

saat ini three.js melakukan 2 dari ini secara eksplisit (penyortiran dan pemusnahan) dan 1 melalui contoh (perender Ray-tracing)

mempertahankan indeks spasial secara internal akan mempercepat penyortiran dan pemusnahan, memberikan lebih banyak manfaat secara progresif untuk adegan yang lebih besar dengan biaya RAM ekstra yang diperlukan untuk menyimpan indeks.

Mengapa Anda tidak menggunakan GPU picking saja? Ada beberapa contoh di sekitar dan cukup mudah untuk diterapkan. Pertunjukannya siang dan malam. Dalam kasus penggunaan kami, dengan model lebih dari satu juta poligon, pengambilan berubah dari hampir satu detik menjadi berjalan secara realtime pada 60fps sambil menyeret berbagai hal di atas model.

https://github.com/brianxu/GPUPicker

@hccampos
Memilih GPU tidak selalu lebih cepat daripada melakukannya di CPU, untuk GPU Anda harus merender pada resolusi yang proporsional dengan presisi yang Anda inginkan, jadi jika Anda menginginkan akurasi piksel - Anda harus merender pada resolusi layar 1:1. Ingatlah bahwa ini adalah render pass yang terpisah, Anda merender objek sebagai warna berbeda yang terpisah. Pass render ekstra berarti penggunaan memori grafis (khas untuk pipa yang ditangguhkan).
Menggunakan indeks partisi ruang biner memberi Anda profil waktu log(n) saat Anda memilih, jadi untuk 1.000.000 poligon Anda akan melihat sekitar 14 operasi untuk menyelesaikan kueri sinar. Bergantung pada struktur data Anda - kemungkinan akan memakan waktu beberapa mikrodetik, memungkinkan Anda ribuan kueri sebelum Anda mulai mengurangi anggaran bingkai Anda.

Mari kita membuat perbandingan, katakanlah Anda memiliki model poli 1m, dan Anda ingin memancarkan sinar dari ruang layar langsung di sepanjang arah kamera ke tempat kejadian (memilih kasus penggunaan). Mari kita asumsikan Anda menggunakan resolusi barel bagian bawah, "full hd", atau 1920 × 1080. Anggap Anda hanya merender RGB (24 bit per piksel), Anda memerlukan 6220800byte (sekitar 6 Mb) atau RAM grafis untuk merender itu. Jika Anda menggunakan solusi CPU, katakanlah Anda menggunakan AABB BVH dengan 10 poligon per daun, itu berarti Anda membutuhkan sekitar 200.000 node, katakanlah setiap node berukuran sekitar 6 * 8byte untuk koordinat, node perantara memiliki tambahan 2 * 4 byte untuk pointer anak dan simpul daun memiliki 10 * 4 byte untuk penunjuk poligon, yaitu 14.400.000 byte (sekitar 14Mb). Perbedaan utama muncul ketika Anda mempertimbangkan fakta bahwa kueri BVH Anda memiliki permintaan yang sangat sedikit pada bandwidth RAM, dibandingkan dengan casing GPU, dan hanya ada sedikit operasi yang terlibat per kueri, dibandingkan dengan rendering geometri poli 1m penuh.
Jika Anda mengambil resolusi yang lebih umum untuk desktop, seperti 2560x1440, Anda akan mendapatkan target render 11059200byte (11Mb).

Jika Anda memiliki anggaran bandwidth ram grafis yang besar dan jumlah inti shader yang cukup baik - tentu saja, itu adalah cara yang sederhana dan mudah untuk melakukan pemetikan.

@Usnul tentu saja, tetapi ini mungkin solusi paling sederhana untuk diterapkan. Menerapkan dan memelihara struktur data indeks spasial mungkin akan menjadi beban yang tidak signifikan bagi pengelola threejs.

Karena itu, saya benar-benar ingin memiliki struktur data indeks spasial yang baik, teruji, dan terpelihara sebagai bagian dari tiga atau sebagai paket npm terpisah.

Saya ingin tahu tentang menerapkan indeks spasial seperti itu untuk geometri bekas saya, jadi saya menerapkan Octree yang cukup sederhana (hanya buat dan cari) yang membagi BufferGeomtry saya. Dengan solusi sederhana ini saya mencapai hasil yang cukup menjanjikan: diterapkan pada geometri dengan sekitar 500K simpul, waktu raycast berkurang dari ~120ms menjadi ~2,3ms. Konstruksi pohon saat ini membutuhkan ~500 md tetapi karena geometri dan pembuatan pohon dilakukan di dalam pekerja web hanya sekali saat aplikasi dimulai, ini bukan masalah.

Saya kira algoritme dapat dengan mudah diintegrasikan ke dalam THREE.BufferGeometry dan mungkin diaktifkan atau dinonaktifkan menggunakan tanda seperti THREE.BufferAttribute 's dynamic . Dengan cara ini, itu hanya bisa digunakan ketika BufferGeometry tidak seharusnya berubah. Sayangnya, saya harus menimpa metode THREE.Mesh 's raycast meskipun saya hanya perlu mengubah dua baris di dalamnya (panggilan pencarian Octree dan iterasi array posisi).

Bagaimanapun, dalam aplikasi VR saya, saya harus mendeteksi tabrakan pengontrol objek selama loop render dan tidak hanya sekali pada klik mouse. Jadi, saya harus mengandalkan solusi saya saat ini. Saya akan mencoba jika saya dapat lebih meningkatkannya.

UPDATE Saya membuat kesalahan dalam mengukur waktu raycast. Nilai yang benar adalah ~2.3ms (bukan ~0.3ms). Saya mengubah nilai di atas sesuai.

Saya pikir memiliki cara ikut serta dalam melakukan pencarian spasial cepat diperlukan di sebagian besar aplikasi yang lebih kompleks yang dibangun di atas three.js. Misalnya, editor 3D. Saya telah bermain-main dengan beberapa implementasi di luar sana, tetapi mereka tidak terintegrasi dengan baik, atau membungkus ke dalam versi three.js tertentu terlalu ketat. Jadi, jika ada yang memiliki cara ikut serta untuk melakukannya tanpa merusak jalur pemutakhiran ke versi three.js yang lebih baru, itu akan sangat bagus.

@matthias-w Saya mencoba raycaster untuk model obj tetapi pengontrol tidak mendeteksi apa pun. Sinar melewati model. Bisakah Anda memberi tahu saya bagaimana Anda memperbaiki masalah itu?

Tentang memiliki indeks spasial opsional. Saya percaya bahwa itu cukup berguna bahkan untuk penyaji itu sendiri (misalnya: untuk pemusnahan) untuk menjadi bagian integral dari mesin. Berikut pembahasan terkait:

13909

Hai! Saya juga agak tertarik dengan ini (walaupun sejak itu saya telah menemukan solusi lain untuk kebutuhan raycast kami), tetapi saya pikir saya juga akan menyumbangkan beberapa eksperimen saya. Ini agak kasar, tetapi saya menggabungkan ini beberapa bulan yang lalu:

https://github.com/gkjohnson/threejs-fast-raycast

Itu menambahkan fungsi computeBoundsTree ke TIGA objek geometri dan menimpa fungsi raycast untuk menggunakannya (dan hanya mengembalikan hit pertama sebagai pengoptimalan tambahan). Ini hanya benar-benar bermanfaat untuk jerat statis yang sangat kompleks dan tidak melakukan apa pun untuk mengelompokkan adegan secara spasial. Berikut demo di mana Anda dapat melihat perbedaan kinerja raycast pada mesh segitiga 80.000. Menghitung pohon batas agak lambat, tetapi dengan sedikit kerja mungkin bisa lebih lancar.

Mengenai pendapat saya tentang ini, saya merasa agak bertentangan. Ini terasa seperti sesuatu yang dapat dibangun dengan cukup baik sebagai ekstensi ke TIGA. Dan pada akhirnya sepertinya melakukan pemeriksaan / tabrakan / gips per segitiga untuk jerat kompleks atau animasi tidak optimal. Dalam kasus sederhana mungkin baik-baik saja, tetapi sepertinya menggunakan representasi bidang / kubus / bola / kapsul yang khas atau mesh yang disederhanakan akan lebih cocok untuk memungkinkan raycasting super cepat (atau oklusi-pemusnahan, tabrakan, dll) dalam kasus yang kompleks. Tentu saja, jika Anda mencari gips dengan piksel sempurna, ini tidak berfungsi dengan baik, tetapi solusi yang tepat sangat bergantung pada kasus penggunaan Anda.

@Usnul @matthias-w Apakah salah satu dari implementasi octree / BVH Anda open source atau tersedia online? Saya pasti tertarik untuk melihatnya!

@gkjohnson

Apakah salah satu dari implementasi octree / BVH Anda open source atau tersedia online? Saya pasti tertarik untuk melihatnya!

Kode ini bukan open source saat ini. Saya bisa memberi Anda sumbernya jika Anda menghubungi saya secara pribadi.

Ada contoh yang saya lakukan untuk instance mesh:
http://server1.lazy-kitty.com/tests/instanced-foliage-1mil/
Contoh di atas termasuk yang berikut:

  • BVH diperbarui secara dinamis saat instance baru dimasukkan ke dalam pohon
  • BVH dioptimalkan secara bertahap menggunakan kedalaman 1-2 rotasi dengan cepat
  • BVH disampel dengan kueri frustrasi ke instance mana yang akan dirender

Saya memiliki versi yang berjalan di game yang sedang saya kerjakan:
http://server1.lazy-kitty.com/komrade/

Sehubungan dengan implementasi Anda. Saya menyukainya, milik saya berbeda dalam 2 cara utama:

  • Saya fokus pada kinerja
  • Saya fokus pada jejak memori
  • Saya menghindari pengumpulan sampah di banyak tempat

Beberapa poin yang lebih spesifik:

  • Saya juga menggunakan campuran strategi pemisahan secara transparan, berdasarkan apa yang ingin Anda lakukan dengan BVH
  • BVH saya berbasis AABB
  • Saya mendukung pembaruan batas simpul melalui pemasangan kembali

@Usnul Saya tidak dapat melihat alamat email Anda atau apa pun, tetapi saya cukup tertarik untuk mempelajari solusi pengindeksan spasial Anda.

Saat ini saya hanya mengulang semua objek pemandangan yang relevan dan menghitung jarak dari kamera. Bukan pendekatan yang paling optimal.

@titansofttime
dia
travnick at gmail com
Tidak menyadari itu tidak tersedia untuk umum. Salahku.

@Usnul Saya tertarik dengan proyek 1 juta juga. Bahkan mungkin 10 atau 20 juta jika memungkinkan. Silakan email saya: kaori.nakamoto. [email protected]

Terima kasih SANGAT ramah!

Maaf untuk respon yang terlambat.
@gkjohnson Kode ini bukan open source. Selain itu, solusi Anda terdengar jauh lebih canggih daripada solusi saya. Jadi, saya kira tidak banyak yang bisa dipelajari dari solusi saya.

@ sid3007 Saya tidak yakin apakah saya mengerti masalah Anda. Saya bisa menjelaskan pendekatan saya. Mungkin itu membantu.

Kasus penggunaan saya cukup sederhana. Saat aplikasi saya dimulai, geometri untuk model yang berbeda dimuat. Model-model ini dapat diubah oleh pengguna. Geometri tidak berubah. Tidak ada deformasi geometri. Oleh karena itu, saya menerapkan Octree yang sangat sederhana yang dibangun sekali untuk setiap geometri saat aplikasi dimulai. Oktre tidak dinamis. Itu dibangun berdasarkan kotak pembatas dari geometri yang diberikan dan array simpul. Selama konstruksinya, ia memeriksa apakah sebuah oktan berisi sebuah simpul atau kotak pembatas Box3 dari oktan berpotongan dengan segitiga (tiga simpul berurutan dalam geometri non-indeks) dan menyimpan referensi larik simpul dengan simpul oktan.
Oktre per-mesh kemudian disimpan bersama dengan mesh. Saya juga menimpa metode THREE.Mesh ' raycast instance mesh saya (hanya satu baris) untuk benar-benar memanggil metode pengujian persimpangan octree. Ini mengembalikan indeks titik wajah geometri yang dapat digunakan oleh logika persimpangan default mesh.
Saya melakukan satu optimasi: pembuatan octree dilakukan setelah aplikasi dimulai di dalam WebWorker (sebenarnya kumpulan pekerja). Alasannya adalah bahwa pembuatan pohon untuk geometri besar membutuhkan waktu yang cukup lama (beberapa detik). Ini akan memblokir UI browser jadi saya memindahkannya ke utas lain.
Saya harap pendekatan saya menjadi jelas.

@matthias-w Kedengarannya seperti pekerjaan yang bagus! Saya secara mandiri melakukan hal yang hampir sama , tetapi tidak berpikir saya mencapai peningkatan kinerja yang hampir sebesar itu. https://discourse.threejs.org/t/octree-injection-for-faster-raytracing/8291/2 (implementasi octree berorientasi objek, dan modifikasi yang kurang bersih pada Mesh.raycast)

Apakah mungkin bagi Anda untuk open-source/berkontribusi implementasi Octree, memungkinkan lebih banyak eksperimen oleh orang lain?

@EliasHasle Terima kasih. Sebenarnya, peningkatan performanya tidak terlalu bagus, karena saya melakukan kesalahan pada langkah pertama saya. Saya mengoreksi nilainya (lihat posting saya di atas). Pengaturan waktu lebih masuk akal sekarang sehubungan dengan kompleksitas pencarian logaritmik Octree. Sayangnya, saya tidak dapat membuat kodenya tersedia saat ini, tetapi mungkin akhir tahun ini. Bagaimanapun, implementasi saya cukup mudah (dan tidak sebersih itu BTW ;)). Jadi saya kira tidak akan ada wawasan khusus.

@matthias-w Saya pikir 2,3 ms vs 120 ms untuk raycast pada mesh vertex 500k masih merupakan peningkatan yang signifikan, yang, misalnya, memungkinkan resolusi real-time peluru yang ditembakkan dalam game (pada sebagian besar perhitungan anggaran per bingkai).

Apakah Anda mencoba raytracing juga?

Apakah implementasi Anda didasarkan pada pohon objek JS? Objek literal atau contoh prototipe? Milik saya sepenuhnya serupa, sehingga setiap simpul adalah oktre, dengan metode dan semuanya.

@EliasHasle

Jika Anda tertarik untuk melakukan raycasting terhadap geometri statis I dan lainnya telah berupaya secara signifikan ke dalam three-mesh-bvh , yang menggunakan BVH untuk mengindeks segitiga dan memungkinkan raycasting berkinerja tinggi serta deteksi persimpangan terhadap geometri kompleks statis. Proses pembangunan pohon lebih kompleks sehingga membutuhkan waktu sedikit lebih lama tetapi membutuhkan raycasting di bawah satu milidetik dan sering di bawah 0.1ms ketika raycasting terhadap geometri dengan ratusan ribu segitiga.

Waktu pembuatan dapat ditingkatkan dalam beberapa cara berbeda tetapi sudah cukup baik untuk apa yang ingin saya lakukan dengannya -- meningkatkan itu ada dalam daftar.

Saya ingin membangun octree berbasis adegan dinamis untuk memungkinkan raycasting dan deteksi tabrakan yang lebih baik untuk adegan dengan banyak jerat, tetapi saya sendiri belum memiliki kasus penggunaan yang baik. Mungkin suatu hari nanti!

@EliasHasle Implementasi saya adalah pohon objek kelas JS (saya menggunakan kelas ES6, yaitu contoh prototipe). Pada dasarnya, sebuah simpul adalah pohon dalam implementasi saya. Namun, saya memiliki kelas Octree tambahan yang menampung simpul akar dan menyediakan metode untuk membangun dan mencari (dan juga beberapa debugging dan visualisasi) pohon.

Saya tidak banyak bereksperimen dengan nilai-nilai untuk tingkat simpul pohon maksimum dan jumlah simpul maksimum per simpul daun. Mungkin ada kombinasi yang lebih baik.
Saya juga menggunakan hierarki volume pembatas untuk mempercepat tes persimpangan. Jadi saya menguji bola pembatas mesh dan kotak pembatas sebelum benar-benar memeriksa oktre geometri mesh.

Saya dapat merekomendasikan sebuah buku yang merupakan kumpulan pendekatan deteksi tabrakan yang sangat bagus: C. Ericson, Deteksi Tabrakan Waktu Nyata, CRC Press, 2004

@gkjohnson Itu tampak hebat! Performanya mengesankan. Apa jenis BVH yang Anda gunakan?

@matthias-w Terima kasih!

Ada beberapa opsi strategi split tetapi memisahkan node BVH di tengah sisi terpanjang akan membangun pohon paling cepat. Segitiga dipartisi menjadi sisi berdasarkan pusat batasnya dan simpul pohon diperluas untuk sepenuhnya memuat segitiga anak (jadi ada sedikit tumpang tindih simpul pohon).

@gkjohnson Jadi implementasi BVH adalah semacam pohon Kd yang tidak seimbang dengan pemilihan sumbu tergantung pada bentuk kotak, bukan? Jika demikian, saya berpikir untuk melakukan sesuatu seperti itu untuk kasus di mana akar BB terlalu jauh dari kubus, dan kemudian menggunakan oktre setelah pemisahan bersyarat. Ini mungkin akan berlaku dengan baik untuk kasus-kasus seperti dunia peta @Usnul , di mana pemisahan awal akan dilakukan dalam dua dimensi "peta" dan pemisahan selanjutnya akan dilanjutkan dalam 3D. Saya pikir ini adalah solusi yang jauh lebih baik daripada solusi saya, yaitu memperluas root BB ke kubus pembatas dengan pusat yang sama, dan kemudian menggunakan pemisahan octree sepenuhnya.

Saya baru saja menerapkan metode yang lebih baik untuk raycasting di PlaneBufferGeometry.

@kpetrow Saya pikir mengoptimalkan raycast pada PlaneBufferGeometry , asumsi bahwa posisi vertex tidak akan diubah kemungkinan besar tidak akan valid untuk geometri resolusi tinggi di mana pencarian linier tidak mencukupi. Sejauh yang saya tahu, penggunaan utama resolusi tinggi PlaneBufferGeometry adalah untuk membentuknya kembali dengan memindahkan simpul, sambil menjaga topologi, misalnya untuk membangun medan.

Menutup mendukung #13909.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat