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?
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.
sumber
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 .
sumber