Mengelola Data Voxel

8

Saya sudah pemrograman di C ++ sebagai hobi selama sekitar 4 bulan sekarang, dan saya benar-benar suka membuat barang menggunakan voxel. Saya menulis "permainan" (Lebih dari sekadar tantangan pribadi, karena saya benar-benar hanya mengerjakan medan, tidak ada gameplay) yang menjadikan dunia seperti Minecraft, tetapi baru-baru ini saya telah berpikir untuk mencoba menulis permainan / tantangan / dll yang menggunakan algoritma seperti Marching Cubes atau Dual Contouring dan mengurangi ukuran voxel. Ketika saya menulis proyek mirip Minecraft, saya menyimpan data masing-masing bongkahan dalam array multidimensi celana pendek yang tidak ditandatangani (sehingga memberi saya 65536 jenis blok berbeda). Selain itu, untuk rendering, saya hanya menyimpan satu titik (sebagai GLubyte) dan satu lagi GLubyte untuk menunjukkan yang mana dari 6 yang menghadap titik yang diwakili. Saya kemudian membuat wajah menggunakan geometri shader.

Dengan proyek baru yang telah saya pikirkan, hal yang tidak dapat saya lewati adalah bagaimana saya bisa menyimpan cukup data voxel untuk membuat voxel sekitar ~ 5cm atau 10cm dibandingkan dengan voxel berukuran 1 m yang saya miliki. Ketika saya membuat blok seluas 704x704x704, proyek lama saya menggunakan sekitar 670MB RAM. Jika saya mengecilkan ukuran voxel menjadi 10cm dan menjaga jarak render yang sama, itu akan menjadi sekitar 649GB data Voxel (dengan asumsi 2 byte per voxel dan area 7040 ^ 3 voxel). Apakah ada cara saya dapat menyimpan data voxel dengan cara yang lebih efisien yang masih memungkinkan saya berbagai jenis voxel?

Bayangan
sumber

Jawaban:

5

Apakah Anda perlu memiliki setiap chunk (anggap Anda menggunakan chunk) dalam memori sekaligus? Beberapa akan tersumbat - terutama di bawah tanah - atau di belakang gunung dll. Lot mungkin hanya udara / kosong dan dapat ditandai dengan bendera.

Anda juga dapat menggunakan LOD octree atau struktur serupa untuk mencoba menjaga detail saat ini terlihat berbanding terbalik dengan jarak dari pengamat. Seperti yang dikatakan oleh Jason, ini jauh lebih mungkin untuk membeli kinerja Anda, tetapi ini adalah perubahan struktural utama dari peta potongan datar.

Lihat artikel ini tentang clipmaps dari blog favorit saya (ia memiliki mesin voxel mirip dengan apa yang Anda gambarkan dengan ukuran voxel ~ a decimetre).

ThorinII
sumber
2
Pertama, ya, saya menggunakan potongan. Kedua, saran Anda tentang bongkar muat yang benar-benar tersembunyi pasti akan membantu sedikit, terima kasih. Tepat di atas kepala saya, metode potensial yang bisa saya gunakan adalah menggunakan kueri oklusi dengan kotak pembatas chunk (karena semua ukuran chunk diketahui) untuk melihat apakah chunk terlihat, dan memuat / membongkar chunk tergantung pada hasilnya. Sunting: Baru saja melihat hasil edit Anda, dan saya sebenarnya sudah melihat blog itu. Itulah alasan saya ingin bereksperimen dengan ukuran voxel yang lebih kecil =)
Shadow
Oklusi jauh lebih penting daripada LOD. Oklusi tidak membuat Anda apa-apa kecuali Anda berada di bawah tanah atau melihat sisi gunung. LOD dengan sendirinya memungkinkan Anda untuk membuat seluruh planet. Pertanyaan oklusi adalah ide yang buruk, karena mereka memperkenalkan round trip GPU-> CPU-> GPU. Meskipun demikian, rendering bersyarat dapat dilakukan, tetapi CPU mungkin dapat melakukan cukup baik sendiri.
Poin bagus. Saya hanya menyatakan LOD kedua karena ini adalah perubahan struktural utama.
ThorinII
3

Pendekatan standar untuk mesin seperti VoxLap Ken Silverman dan penggantinya Ace of Spades, adalah dengan menggunakan kompresi RLE dan beberapa trik tingkat bit lainnya untuk menyimpan dan mengakses data. Kompresi 1D semacam ini cenderung sangat efisien dan jauh lebih mudah digunakan daripada octrees. Saya percaya mesin Silverman mencapai resolusi voxel sekitar 10cm. Sesuatu yang tidak biasa Anda lihat hari ini, dan yang dicapai pada perangkat keras yang jauh lebih lemah.

Saya percaya juga benar bahwa pendekatannya tidak menyimpan warna untuk voxel yang tidak terpapar, bahwa itu malah menghitung warna untuk voxel permukaan sebagai fungsi ketinggian, atau dengan mengingat area medan mana yang telah diledakkan terbuka dan mewarnai ini sebagai "tanah segar". ". Anda bisa menggunakan semacam fungsi kontinu seperti perlin noise untuk melakukan ini, tetapi ini bisa dengan cepat menjadi mahal untuk area permukaan yang luas (kecuali, mungkin, dilakukan pada GPU).

Oktaf tidak buruk, tetapi mereka sulit digunakan dalam praktiknya, dan alokasi cache yang efisien jauh lebih menantang daripada RLE, yang mudah linierkan dengan chunk. Makalah seminal Tero Karras dan Samuli Laine tentang SVO menunjukkan betapa banyak upaya yang dilakukan untuk benar-benar berkinerja penerapan oktaf - dan itu sedang mempertimbangkan hanya rendering, bukan gameplay atau komunikasi jaringan.

Insinyur
sumber
0

Saya tidak tahu seberapa jauh Anda telah melangkah dalam proyek Anda, tetapi saya dan seorang teman saya menggunakan algoritma Dual Marching Cubes , berdasarkan struktur chreek Octree dan menggunakan kisi ganda untuk membuat data. Ini memiliki banyak keuntungan, seperti kehabisan memori yang sangat rendah dan rendering yang sangat cepat. Mungkin agak sulit untuk menerapkan Level Of Detail (LOD) di perbatasan chunk dengan chunk lainnya, tetapi jika Anda memiliki waktu luang, Anda dapat mengetahui bagaimana pengembang Ogre3D melakukannya .

Leggy7
sumber