Saya sebelumnya telah menerapkan marching cubes / tetrahedra untuk membuat IsoSurface. Ini berhasil ( YouTube ), tetapi kinerjanya sangat buruk karena saya tidak pernah menerapkan variabel Tingkat Detail berdasarkan jarak tampilan (atau bahkan menghapus potongan lama yang jauh).
Saya memutuskan untuk mencoba lagi dan melakukannya dengan benar kali ini. Saya sudah mulai dengan membuat OctreeNode yang berfungsi sebagai berikut ketika Build()
dipanggil.
- Jika potongan terlalu kecil untuk dibangun, segera kembali.
- Berolahraga jika permukaan melewati volume chunk ini.
- Jika demikian, maka putuskan apakah kita ingin menaikkan LOD (karena kamera dekat)
- Jika demikian, maka bibit 8 anak dan memanggil proses yang sama pada mereka
- Jika tidak, bangun mesh menggunakan dimensi node saat ini
Beberapa PseudoCode:
OctNode Build() {
if(this.ChunkSize < minChunkSize) {
return null;
}
densityRange = densitySource¹.GetDensityRange(this.bounds);
if(densityRange.min < surface < densityRange.max) {
if(loDProvider.DesiredLod(bounds)² > currentLoD) {
for(i 1 to 8) {
if(children[i] == null) {
children[i] = new OctNode(...)
}
children[i] = children[i].Build();
}
} else {
BuildMesh();
}
return this;
}
}
¹ Selain mengembalikan kerapatan pada suatu titik, sumber kerapatan dapat menentukan kisaran kerapatan yang mungkin untuk volume tertentu.
² Penyedia LoD mengambil kotak pembatas dan mengembalikan max yang diinginkan berdasarkan posisi kamera / frustrasi, pengaturan pengguna, dll ...
Jadi ... Ini semua bekerja dengan cukup baik. Menggunakan bola sederhana sebagai sumber Kepadatan, dan menampilkan semua node:
Dan hanya daunnya saja:
Namun, ada beberapa masalah:
- Saya harus mendefinisikan volume pembatas awal (dan semakin besar itu, semakin banyak pemrosesan yang harus saya lakukan)
- Pada akar pohon, saya tidak tahu seberapa dalam daunnya, jadi penomoran LoD saya dimulai pada kualitas terendah (root) dan meningkat ketika potongan semakin kecil. Karena LoD sekarang relatif terhadap volume awal, itu tidak banyak digunakan ketika saya ingin melakukan hal-hal pada ukuran / kualitas tertentu.
Saya telah memikirkan beberapa opsi tetapi keduanya tampak cacat:
- Pelihara koleksi Octrees dan tambah / hapus tergantung jarak. Tidak dapat melihat bagaimana saya menyatu dengan baik¹, ditambah lagi saya membutuhkan daftar node yang dikenal-kosong, terutama jika saya ingin permukaan 3D sewenang-wenang (untuk menghindari penghitungan ulang volume kosong berulang kali)
- Tambahkan induk Node ke root saat ini, lalu tambahkan tujuh saudara kandung untuk simpul asli. Ini akan bekerja dan sesuai permintaan tetapi tampaknya rumit untuk menyusut kembali dengan masuk akal ketika pemain bergerak melalui lanskap. Itu juga akan membuat angka LoD menjadi kurang berarti.
¹ [Dalam klarifikasi ke Q di bawah] Saat ini, jika 2 node yang berdekatan secara fisik di pohon berada di LOD yang berbeda, saya memiliki beberapa kode untuk memaksa verts sehingga tidak ada jahitan saat jerat dihasilkan. Saya dapat melakukan ini dengan mengetahui kepadatan untuk beberapa node di sekitarnya. Dalam skenario di mana saya memiliki 2 oktober independen berdampingan, saya tidak punya cara mudah untuk mengambil informasi ini, menghasilkan jahitan.
Apa cara optimal untuk mendekati ini?