Mengatasi keterbatasan float untuk dunia seukuran planet di Unity

8

Sejauh yang saya tahu, melangkah lebih jauh dari 1 juta unit dari dunia asal di Unity hampir tidak mungkin karena masalah presisi floating point.

Membuat dunia lebih dari 1M unit dalam radius akan membutuhkan baik menggunakan doublevars untuk koordinat atau memanfaatkan beberapa teknik pembagian ruang untuk membagi adegan besar menjadi potongan hirarkis dengan yang terkecil dari mereka sekitar 10.000 unit, yaitu setiap posisi ruang-dunia akan diekspresikan oleh hierarki chunk objek dalam dan sekelompok floatvars mewakili posisi lokalnya (dan mungkin rotasi dan scaling) di dalam chunk terakhir.

Either way, melakukan ini akan membutuhkan penerapan sistem koordinat baru yang lengkap, jadi saya ingin tahu apakah itu mungkin atau tidak di Unity, dan jika demikian, bagaimana saya membuatnya bekerja dengan sistem Unity yang ada seperti fisika dan sebagainya.

PS Saya tidak bisa begitu saja mengubah dunia menjadi asal ketika pemain bergerak karena saya ingin semua hal terjadi secara bersamaan di seluruh planet ini.

Terima kasih!

Maks Maisak
sumber

Jawaban:

5

Anda berpikir dalam istilah yang sangat statis.

Hanya karena sebuah objek berjarak setengah dunia tidak memerlukan masalah apa pun. Jika koordinat entitas disimpan relatif ke chunk daripada relatif ke dunia, ini sepele untuk dicapai. Selamat datang di cara yang harus Anda lakukan jika Anda menulis dunia voxel dalam kode asli.

Jadi mari kita asumsikan konsep yang disebut locales . Ini adalah satu set bongkahan yang berdekatan satu sama lain. Yang penting adalah ruang apung internal ke lokasi tertentu tidak pernah melebihi batas keamanan. Anda perlu menentukan apa lokasi pemrosesan diskrit Anda, mulai dengan mengambil semua potongan yang berada dalam radius posisi entitas n (bisa jadi pemain atau yang lain). Di mesin saya saat ini, saya memastikan bahwa jika bahkan satu potong dari dua lokal yang berbeda tumpang tindih, bahwa lokal ini bergabung menjadi satu lokal / set potongan unik. Ini memastikan bahwa Anda tidak pernah memproses semua entitas dalam satu potongan tunggal lebih dari sekali, dalam bingkai tertentu.

Sekarang setelah Anda memiliki lokal / chunk-set, Anda dapat melakukan logika permainan pada mereka dan isinya. Dan tidak masalah seberapa jauh mereka dari pemain atau dari tempat asalnya. Yang penting adalah Anda mendapatkan bongkahan yang kira-kira pusat untuk setiap set, perlakukan itu sebagai asal yaitu float[0,0,0.0.0.0], dan lakukan cara Anda keluar dari sana. Dengan rentang tampilan yang khas dalam sebuah game, saya jamin Anda tidak perlu melihat lebih dari beberapa km, yang sangat bisa dilakukan float, tanpa masalah serius.

Selain dari Unity, satu opsi adalah menulis mesin dari awal, saya kira, dan menggunakan sesuatu seperti libfixmath, di mana Anda masih dapat menggunakan titik desimal tetapi karena mereka tidak mengambang , mereka tidak akan pernah memiliki masalah akurasi ini. Tapi saya jamin Anda akan perlu potongan dan lokal untuk alasan lain, jadi mungkin tidak sepadan dengan usaha.

Insinyur
sumber
Anda mengatakan bahwa saya tidak akan pernah perlu melihat lebih dari beberapa km jauhnya, tetapi bagaimana dengan dunia seukuran planet, yang harus saya amati sepenuhnya dari ruang angkasa (lihat outerra )?
Maks Maisak
@MaksimMaisak Game logic membutuhkan ketelitian numerik; rendering tidak. Anda tidak akan pernah perlu melihat dunia yang detail dan tepat dari luar angkasa. Ada ketinggian tertentu di mana Anda dapat beralih dari sistem akurat, di lapangan yang telah saya jelaskan di atas, ke perspektif ruang-kurang akurat, mulus (jika Anda memainkan kartu Anda dengan benar). Tapi ingatlah ada perbedaan antara rendering dan logika game.
Insinyur
Dan bagaimana Anda membagi ruang menjadi potongan-potongan? Apakah Anda mulai dengan potongan dan mengelompokkannya menjadi lokal, atau mulai dengan lokal dan membaginya menjadi potongan?
Maks Maisak
Anda mulai dengan bongkahan. "Lokal" di sini hanya berarti "lingkungan bongkahan" sehingga konsep bongkahan adalah prasyarat.
Insinyur
Bagaimana sepotong bisa 'tumpang tindih'?
Maks Maisak
6

Itu pertanyaan yang sering muncul. Saya akan mengambil kebebasan untuk meneruskan Anda ke jawaban lain yang cukup terperinci yang telah saya berikan untuk masalah yang sama, alih-alih hanya mengulanginya di sini: Apakah sistem koordinat kustom dimungkinkan di Unity

Dari sana, apa yang paling saya sarankan adalah Anda membaca makalah yang luar biasa di: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.471.7201&rep=rep1&type=pdf . Ini membandingkan beberapa cara untuk mengatasi masalah yang Anda gambarkan (termasuk koordinat lokal, seperti yang dijelaskan oleh Arcane Engineer dalam jawabannya) dan masuk ke detail tentang solusi asal-mengambang yang terkenal saat ini. Yang sebenarnya adalah apa yang akan saya gunakan dalam banyak kasus (pada kenyataannya, itulah yang saya gunakan dalam aplikasi saya).

Tentu, Anda menyebutkan solusi asal float tidak sesuai dengan kebutuhan Anda. Tapi itu mungkin tidak menjadi masalah bahkan jika Anda ingin hal-hal terus terjadi di bagian dunia yang sangat jauh. Anda dapat memiliki hampir semua AI yang terjadi di mana pun Anda inginkan - Anda tidak seharusnya melakukan pemeriksaan tabrakan atau penentuan posisi yang tepat terlalu jauh dari pemain (yaitu di luar ambang ketidaktepatan float). Tapi bagaimanapun, sejujurnya, dalam aplikasi nyata Anda mungkin tidak akan pernah bisa memiliki banyak tabrakan dan pemosisian dalam permainan karena keterbatasan pemrosesan. Dan masih, mungkin ada solusi bahkan untuk batasan yang Anda lihat pada solusi asal mengambang, tergantung pada karakteristik permainan Anda. Sekali lagi, saya sarankan Anda tidak membuang solusi itu sebelum membaca lebih menyeluruh tentang hal itu.

Namun, jika Anda memutuskan bahwa Anda harus mencoba sistem koordinat lokal (yang bisa menjadi solusi yang sangat kompleks tergantung di mana Anda pergi dengannya), maka item kedua dalam jawaban saya yang tertaut adalah untuk Anda. Bagian paling penting di sana adalah kertas yang ditulis oleh pria yang pertama kali mengimplementasikan solusi itu dalam game perintis Dungeon Siege: http://scottbilas.com/files/2003/gdc_san_jose/continuous_world_paper.pdf

Ada juga video dari beberapa tahun yang lalu, di mana orang-orang dari Unity mengomentari solusi itu dan bahkan menjelaskan implementasi modern dari konsep di Unity:

https://www.youtube.com/watch?v=VKWvAuTGVrQ

Semoga ini bisa membantu.

Dan
sumber
3

Tidak yakin apakah Anda telah menyetujui suatu solusi, tetapi saya ingin menyebutkan dua sumber daya lain yang mungkin berguna bagi Anda dan pembaca lain di masa depan.

  • Pembicaraan CppCon baru-baru ini: "Demystifying Floating Point" , yang sangat relevan terlepas dari bahasa pemrograman. Satu hal yang sangat menarik yang disajikan tentang presisi adalah bahwa sweet-spot akurasi float berada di antara rentang [-1, + 1]. Jadi pelampung yang dinormalisasi adalah cara terbaik untuk pergi jika Anda bisa menggunakannya.

  • Tempat lain yang mungkin ingin Anda tinjau untuk mendapatkan beberapa gagasan adalah dalam permainan Dungeon Siege klasik . Gim ini menggunakan sistem dunia kontinu yang berbasis simpul / ubin dan setiap posisi relatif terhadap simpul saat ini. Ada deskripsi yang sangat rinci tentang sistem yang digunakan oleh game di whitepaper ini . Saya juga menulis beberapa paragraf tentang itu di blog saya . Pengaturan ini adalah novel pada saat itu, tetapi mungkin tidak berguna hari ini, makalah yang terkait di atas menyebutkan beberapa masalah yang mereka miliki. Meskipun demikian, ini menarik dari perspektif sejarah dan mungkin masih melayani Anda sebagai sumber ide dan inspirasi.

Glampert
sumber