Bagaimana cara menyimpan sumber daya di sistem rendering homebrew saya


10

Latar Belakang:

Saya merancang sistem render 3D sederhana untuk arsitektur tipe sistem komponen entitas menggunakan C ++ dan OpenGL. Sistem terdiri dari renderer dan grafik adegan. Ketika saya menyelesaikan iterasi pertama renderer, saya mungkin mendistribusikan grafik adegan ke arsitektur ECS. Untuk sekarang ini adalah placeholder dengan satu atau lain cara. Jika memungkinkan, berikut ini adalah tujuan saya untuk pemberi render:

  1. Kesederhanaan . Ini untuk proyek penelitian dan saya ingin dapat dengan mudah mengubah dan memperluas sistem saya (karenanya pendekatan ECS).
  2. Performa . Adegan saya mungkin memiliki banyak model kecil dan volume besar dengan banyak geometri. Tidak dapat diterima untuk memperoleh objek dari konteks OGL dan geometri buffer setiap bingkai render. Saya bertujuan untuk lokalitas data untuk menghindari kesalahan cache.
  3. Fleksibilitas . Itu harus dapat membuat sprite, model, dan volume (voxels).
  4. Terpisah . Grafik adegan dapat di refactored ke arsitektur ECS inti setelah saya menulis renderer saya.
  5. Modular . Alangkah baiknya bisa menukar penyaji yang berbeda tanpa mengubah grafik adegan saya.
  6. Transparansi referensial , artinya pada suatu saat saya dapat memberikannya adegan yang valid dan itu akan selalu membuat gambar yang sama untuk adegan itu. Tujuan ini khususnya tidak selalu diperlukan. Saya pikir ini akan membantu menyederhanakan adegan serialisasi (saya harus dapat menyimpan dan memuat adegan) dan memberi saya fleksibilitas untuk bertukar dalam adegan yang berbeda selama runtime untuk keperluan pengujian / eksperimen.

Masalah dan ide:

Saya telah datang dengan beberapa pendekatan berbeda untuk mencoba tetapi saya berjuang dengan cara men-cache sumber daya OGL (VAO, VBO, shader, dll) untuk setiap node render. Berikut ini adalah konsep caching yang berbeda yang telah saya pikirkan sejauh ini:

  1. Cache terpusat. Setiap node adegan memiliki ID dan renderer memiliki cache yang memetakan ID ke render node. Setiap node render berisi VAO dan VBO yang terkait dengan geometri. Cache yang ketinggalan memperoleh sumber daya dan memetakan geometri ke simpul render dalam cache. Ketika geometri diubah, bendera kotor diatur. Jika penyaji melihat bendera geometri yang kotor saat iterasi melalui node adegan, itu menolak data menggunakan node render. Ketika node adegan dihapus, sebuah acara disiarkan dan renderer menghapus simpul render terkait dari cache saat melepaskan sumber daya. Atau, simpul ditandai untuk dihapus dan renderer bertanggung jawab untuk menghapusnya. Saya pikir pendekatan ini paling dekat mencapai tujuan 6 sementara juga mempertimbangkan 4 dan 5. 2 menderita kompleksitas tambahan dan hilangnya data lokalitas dengan pencarian peta, bukan akses array.
  2. Tembolok yang didistribusikan . Mirip di atas kecuali setiap adegan memiliki simpul render. Ini memintas pencarian peta. Untuk mengatasi lokalitas data, node render dapat disimpan di renderer. Kemudian node adegan malah bisa memiliki pointer untuk membuat node dan renderer menetapkan pointer pada cache miss. Saya pikir jenis ini meniru pendekatan komponen entitas, sehingga akan konsisten dengan seluruh arsitektur. Masalahnya di sini adalah bahwa sekarang node adegan menyimpan data renderer-implementasi-spesifik. Jika saya mengubah cara merender di renderer (seperti rendering sprite vs volume) sekarang saya perlu mengubah render node atau menambahkan lebih banyak "komponen" ke node adegan (yang berarti mengubah grafik adegan juga). Di sisi positifnya, ini sepertinya cara paling sederhana untuk mengaktifkan dan menjalankan renderer iterasi pertama saya.
  3. Metadata terdistribusi . Komponen metadata cache penyaji disimpan di setiap adegan adegan. Data ini tidak khusus untuk implementasi, melainkan memiliki ID, tipe, dan data relevan lainnya yang dibutuhkan oleh cache. Kemudian pencarian cache dapat dilakukan secara langsung dalam array menggunakan ID, dan jenisnya dapat menunjukkan jenis pendekatan rendering yang digunakan (seperti sprite vs volume).
  4. Pengunjung + pemetaan terdistribusi . Perender adalah pengunjung dan node adegan adalah elemen dalam pola pengunjung. Setiap node adegan menyimpan kunci cache (seperti metadata tetapi hanya ID) yang hanya dimanipulasi oleh renderer. ID dapat digunakan untuk larik alih-alih pencarian peta umum. Renderer dapat mengizinkan adegan adegan untuk mengirim fungsi rendering yang berbeda berdasarkan pada jenis adegan adegan, dan ID dapat digunakan oleh cache apa pun. ID default atau di luar jangkauan akan menunjukkan kehilangan cache.

Bagaimana Anda memecahkan masalah ini? Atau Anda punya saran? Terima kasih telah membaca dinding teks saya!


1
Sudahkah Anda membuat kemajuan?
Andreas

Ini adalah pertanyaan yang sangat kompleks, dan mungkin harus dipecah menjadi beberapa pertanyaan terpisah. Ini pada dasarnya bertanya, "Bagaimana saya harus merancang mesin saya?" Saran saya adalah mendesain sesuatu yang mendukung komponen yang lebih sederhana terlebih dahulu, kemudian menambahkan dan memperbaiki fitur saat Anda menggunakannya. Juga, cari buku desain mesin game 3D, yang seharusnya mencakup banyak informasi yang Anda cari.
Ian Young

Jawaban:


2

Setelah membaca kembali pertanyaan Anda, saya merasa Anda terlalu rumit masalahnya. Inilah alasannya:

  1. Hanya ada dua jenis sistem rendering: Maju, dan Ditangguhkan, tidak ada yang bergantung pada grafik adegan.

  2. Satu-satunya masalah kinerja yang harus Anda dapatkan dengan sistem render apa pun, harus berasal dari jumlah poli yang tinggi, dan kode klien dan shader yang tidak efisien.

  3. Kehilangan cache memang mengurangi kinerja, tetapi mereka bukan monster seperti yang Anda kira. 80% peningkatan kinerja Anda akan berasal dari algoritma yang lebih efisien. Jangan membuat kesalahan dengan mengoptimalkan kode Anda.

Yang mengatakan:

Jika Anda menggunakan scenegraph homebrew maka Anda harus sudah menggunakan antarmuka "Renderer" (atau kelas dasar) untuk merancang bagian rendering dari kode scenegraph Anda. Pola pengunjung menggunakan pengiriman ganda adalah pendekatan yang baik untuk ini, karena Anda mungkin menggunakan banyak jenis node grafik seperti warna, tekstur, mesh, transformasi dll. Dengan cara ini, selama siklus render, yang harus dilakukan oleh renderer adalah berjalan struktur pohon adegan kedalaman-pertama, melewati dirinya sebagai argumen. Dengan cara ini renderer pada dasarnya hanyalah kumpulan shader dan mungkin satu atau dua framebuffer. Hasil dari ini adalah bahwa kode pencarian / penghapusan tidak lagi diperlukan untuk sistem rendering, hanya skenegraf itu sendiri.

Tentu saja ada cara lain untuk mengatasi masalah yang Anda hadapi, tetapi saya tidak ingin memberikan jawaban yang terlalu panjang. Jadi, saran terbaik saya adalah membuat sesuatu yang sederhana bekerja terlebih dahulu, kemudian mengembangkannya untuk menemukan kelemahannya, kemudian bereksperimen dengan pendekatan lain dan melihat di mana kekuatan / kelemahan mereka dalam praktik.

Kemudian Anda akan ditempatkan dengan baik untuk membuat keputusan.

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.