Di three.js kita cukup menggabungkan geometri untuk membatasi jumlah panggilan draw dan dengan demikian meningkatkan kinerja. Dalam tes sederhana dengan satu bahan, saya bisa menggambar 50.000 kubus + bayangan @ 60fps pada GPU GTX660 saya. Tanpa penggabungan geometri, 5.000 kubus sudah menyebabkan masalah.
Saya bertanya-tanya bagaimana cara mempertahankan manfaat dari setiap mesh kubus itu sendiri. Sebagai contoh, bagaimana cara memilih mesh kubus ketika semuanya digabung menjadi satu geometri? Secara default itu tentu saja tidak mungkin.
Apakah ada teknik umum untuk masalah ini? Lagipula saya memang memiliki semua objek mesh yang tidak terputus bahkan setelah penggabungan. Jadi harus ada cara untuk memanfaatkannya untuk dipetik?
Singkatnya, apa yang ingin saya lakukan
- SimCity menyukai game untuk tujuan belajar
- Setiap rumah adalah jala kubus
- Ingin merender 50.000 rumah dan dapat menambah & menghapus rumah
- Pemilihan rumah melalui kursor mouse (memetik) harus dimungkinkan
Jawaban:
OK aku mengerti. Setelah menggabungkan seluruh geometri menjadi satu, saya masih memiliki jerat individual dalam sebuah array. Jadi saya bisa menggunakan jerat ini untuk raycasting, meskipun mereka bahkan tidak dirender. Butuh waktu beberapa saat untuk menyadari hal ini.
Untuk memilih saya menggunakan implementasi octree ini: http://threejs.org/examples/#webgl_octree_raycasting
Ini menurunkan tes persimpangan per pembaruan dari 50.000 menjadi ~ 500. Tanpa octree, fps akan berkurang banyak.
Lambung pemetik oranye yang Anda lihat sebenarnya adalah jaring yang sekarang dirender (+1 draw call) dengan bahan yang diubah dan ukuran yang dimodifikasi.
Jadi saya kira langkah selanjutnya adalah mengimplementasikan semacam partisi peta. Artinya, pisahkan geometri yang digabungkan menjadi beberapa bagian. Alasan untuk ini adalah bahwa geometri yang digabungkan memiliki sejumlah besar simpul. Itu berarti Jika saya memindahkan peta 99% dari layar, kartu grafis masih harus memproses semua simpul karena geometri masih dalam pandangan, setidaknya 1% darinya. Jadi jika itu rusak, hanya potongan-potongan yang terlihat harus dirender.
sumber
Untuk memilih, Anda juga dapat merender ID untuk setiap kubus ke target render lain dan hanya memeriksa apa nilai ID pada kursor. Keuntungannya adalah bahwa pengambilan pixel sempurna dan bekerja secara efisien juga untuk geometri yang lebih kompleks.
Jika semua objek memiliki geometri yang sama, maka Anda dapat menggunakan render yang dipasang. Satu aliran mendefinisikan geometri, sementara yang lain mendefinisikan properti per instance (misalnya transformasi). Untuk pemusnahan frustrasi Anda perlu membangun aliran contoh setiap frame berdasarkan tes visibilitas. Jika Anda memiliki sejumlah besar objek, Anda mungkin ingin meletakkan objek-objek itu ke dalam satu oktree longgar atau sesuatu untuk mempercepat pemusnahan.
sumber
Saya tidak yakin tentang rincian three.js, tetapi dua kemungkinan babi kinerja muncul dalam pikiran secara umum OpenGL:
sumber
Pendekatan lain yang dapat Anda ambil adalah membangun beberapa atribut vertex ke dalam geometri Anda dan memasukkan logika highlight ke shader fragmen Anda. Ini sangat berguna ketika Anda tidak ingin memiliki dua salinan data dalam memori, dan Anda akan memiliki kontrol lebih besar tentang bagaimana sorotan diterapkan.
sumber