Bagaimana cara membuat jala medan besar secara efisien?


10

Baru-baru ini saya terjebak pada masalah memikirkan cara terbaik untuk menghasilkan medan ke dalam permainan saya. Dalam proyek lain saya biasanya menggunakan pemetaan ketinggian, jadi semua pekerjaan inti didasarkan pada mesin yang digunakan, tetapi sekarang ini tidak dapat dilakukan karena medannya memiliki jutaan poligon tertentu yang harus digambar dengan akurat. Juga, banyak dari mereka tidak dapat diuraikan dari vektor Y (karena poligon tersembunyi di bawah), yaitu, peta ketinggian tidak berguna di sini. Dalam hal ini saya harus menggunakan objek COLLADA.

Seseorang mengatakan kepada saya untuk secara manual membagi model di dalam perangkat lunak seperti Blender, tetapi sayangnya ini juga tidak mungkin karena medan ini dibuat dalam potongan-potongan dalam perangkat lunak lain dan dimuat setelahnya ke dalam permainan (itulah idenya). Oleh karena itu ini akan menjadi pekerjaan besar yang wajib memotongnya secara manual setiap kali.

Jadi, sejak seminggu saya telah mempelajari tentang bagaimana saya bisa menyelesaikan masalah ini dan secara prosedural memuat mesh ini, medan, sesuai dengan frustrasi kamera, menghemat kinerja sebanyak mungkin. Saya datang di banyak dokumen tentang generasi mesh prosedural dan saya pikir masalah saya dapat diselesaikan dengan memetakan mesh ke dalam octrees. Ini adalah pekerjaan BESAR, setidaknya bagi saya, dan itulah sebabnya saya di sini, karena saya tidak ingin mengambil risiko mengambil jalan yang salah tanpa sebelum mendengar dari orang yang berpengalaman.

Singkatnya, saya memiliki jutaan simpul dan indeks yang bersama-sama membentuk medan, tetapi untuk alasan yang jelas saya tidak bisa menggambarnya secara bersamaan. Dibutuhkan semacam prosedur. Apa cara terbaik untuk melakukan itu, memperlakukan jala besar sebagai medan? Apakah ada buku khusus tentang itu? Apakah ada cara terbaik untuk mengimplementasikannya?

Maaf atas kesalahan apa pun, saya sangat pemula di bidang ini.

Jawaban:


12

Pemotongan dasar adalah cara yang baik untuk memulai. Anda dapat pindah ke struktur data yang lebih canggih seperti oktri nanti, jika perlu. Untuk saat ini, cukup bagi medan Anda menjadi potongan dimensi yang diberikan saat memuat model dari disk.

Bergantung pada data Anda, Anda mungkin ingin membagi medan menjadi pilar-pilar di pesawat yang membentang setinggi penuh, atau dalam kubus di ruang angkasa. Kode tidak lengkap (fmod, inisialisasi vektor, indeks, ...) tetapi harus memberi Anda awal.

// Load vertices from disk
struct point { double x, y, z; };    
vector<point> vertices;

// Create container for chunks
typedef pair<int, int> key;
unordered_map<key, vector<point>> chunks;
const int chunksize = 10;

// For each vertex
for (int i = 0; i < vertices.size(); ++i) {
    // Fetch global coordinates
    int x = vertices[i].x,
        y = vertices[i].y,
        z = vertices[i].z;

    // Find containing chunk
    key k;
    k.first  = x / chunksize;
    k.second = z / chunksize;

    // Calculate local coordinates
    point p;
    p.x = x % chunksize;
    p.y = y;
    p.z = z % chunksize;

    // Add to chunk
    chunks[k].push_back(p);
}

// Create separate buffers for each chunk
// ...

Karena Anda telah memisahkan mesh sekarang, Anda dapat melakukan teknik LOD dan menyisihkannya untuk melewati rendering potongan tersembunyi.

  • Lihat jarak adalah tempat Anda memulai. Anda hanya akan membuat potongan dalam jarak tertentu, misalnya jarak tampilan kamera Anda. Semakin kecil jarak pandang, semakin banyak kinerja yang Anda dapatkan karena potongan medan yang lebih sedikit harus ditarik.

  • Frustum culling adalah teknik umum untuk hanya membuat jerat yang bersinggungan dengan frustum tampilan kamera. Ini kemungkinan besar akan memberi Anda keuntungan kinerja terbesar.

Lakukan percobaan dengan ukuran chunk dan lihat jarak untuk mendapatkan hasil terbaik. Ukuran chunk merupakan trade-off antara culling akurat versus komputasi mudah. Untuk lebih mengoptimalkan, Anda bisa melihat ini optimasi yang lebih maju.

  • Pemusnahan oklusi dapat dilakukan dengan memberikan jerat pada CPU pada resolusi yang sangat rendah. Ini memungkinkan Anda untuk mendeteksi jerat yang tersembunyi di belakang yang lain. Mereka tidak harus dikirim ke GPU, jadi Anda menyimpan banyak eksekusi vertex shader yang jika tidak akan dilakukan sebelum menolak segitiga.

  • Level detail berarti Anda menghitung jerat resolusi yang lebih rendah dari potongan Anda. Berdasarkan jarak ke kamera, Anda memilih salah satu jerat untuk menggambar. Ini memungkinkan Anda untuk mengurangi jumlah simpul karena bongkahan jauh tidak perlu begitu banyak detail. Pendekatan ini cocok dengan oktaf karena Anda bisa menggabungkan beberapa kubus menjadi satu mesh resolusi rendah untuk area yang jauh dari kamera. Namun, tidak mudah untuk menggabungkan tepi antara dua potongan dengan resolusi yang berbeda.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.