Mengoptimalkan game XNA 2D


56

Apakah masuk akal untuk mengimplementasikan logika untuk melewati render objek di luar viewport atau haruskah saya tidak peduli dan membiarkan Framework melakukannya?

Jawaban:


79

Pemusnahan adalah pengoptimalan kinerja. Jadi tidak masuk akal untuk melakukannya hanya demi itu. Anda harus punya alasan.


GPU (bukan Kerangka Kerja XNA) mengupas segitiga dan piksel dengan kecepatan sangat menyilaukan. Setiap segitiga yang Anda kirim harus diubah (melalui vertex shader Anda). Kemudian itu mengambil yang mendarat dari layar. Kemudian ia mengisi segitiga yang tersisa, menyisihkan piksel yang berada di luar layar. Pixel yang tersisa kemudian ditarik ke buffer belakang (melalui pixel shader Anda).

(Ketika saya mengatakan "lalu" - itu benar-benar melakukan semua ini dalam pipa paralel masif.)

Jadi sangat jarang dan tidak biasa bahwa Anda mungkin harus menyisihkan segitiga individu. Untuk mencapai batas titik Anda harus menggambar sejumlah besar segitiga yang tidak masuk akal. Untuk menekan batas fill-rate, tekstur-ambil atau pixel-shading, Anda biasanya perlu memiliki kompleksitas kedalaman tinggi (dalam hal ini viewport / frustum culling tidak akan membantu).


Jadi biasanya ada sedikit atau tidak ada biaya untuk memiliki geometri di luar layar.

Biaya - terutama dalam konteks menggambar "objek" (biasanya objek 3D) - sebenarnya dalam mengirimkan objek-objek ke GPU di tempat pertama . Kirim terlalu banyak objek dan Anda mencapai batas batch Anda (Anda mendapatkan beberapa ribu * batch per frame).

Saya sarankan membaca jawaban ini dan dek geser yang ditautkan ini untuk deskripsi mendalam tentang kumpulan.

Karena itu, jika Anda menerapkan pemusnahan frustum, Anda dapat mengurangi jumlah batch yang Anda kirim ke GPU. Jika Anda terbatas batch - ini bisa membuat Anda di bawah batas.


Sekarang - pertanyaan Anda adalah tentang XNA 2D - jadi mungkin Anda gunakan SpriteBatch. Ini agak berbeda.

Bukan kesalahan bahwa itu disebut "Sprite Batch ". Apa yang dilakukannya adalah mengambil sprite yang Anda gambar dan melakukan yang terbaik untuk mengirimkan sprite tersebut ke GPU dalam batch sesedikit mungkin dengan menggabungkannya.

Tetapi SpriteBatch akan dipaksa untuk memulai batch baru jika:

  • Anda menggambar lebih banyak sprite daripada yang bisa masuk ke dalam satu batch (2048 sprite di XNA 4)
  • Anda mengubah tekstur (inilah sebabnya ada opsi pengurutan menurut tekstur)

Jadi pemusnahan adalah pengoptimalan yang cocok jika Anda mengalami yang pertama. Jika Anda mengirim sejumlah besar sprite sehingga Anda memiliki terlalu banyak batch (Anda mungkin menggunakan bandwidth juga - tapi saya cukup yakin Anda akan mencapai batas batch terlebih dahulu). Ini umumnya hanya akan terjadi jika Anda memiliki dunia yang benar-benar luar biasa - sehingga Anda umumnya dapat lolos dengan penyisihan yang sangat sederhana, cepat namun tidak akurat dalam kasus ini.

Sekarang - Jika Anda menggambar dengan swap tekstur yang cukup untuk membawa Anda melewati batas batch, dan banyak dari mereka benar-benar di luar layar dan memusnahkannya akan membuat Anda di bawah batas batch. Lalu ya - pemusnahan adalah optimasi yang akan bekerja.

Namun - optimasi yang lebih baik untuk mengejar dalam hal ini adalah dengan menggunakan atlas tekstur (alias: sprite sheets). Ini memungkinkan Anda untuk mengurangi jumlah pertukaran tekstur dan karenanya batch - terlepas dari apa yang ada di layar atau tidak. (Ini adalah alasan utama Anda dapat menentukan kotak sumber untuk sprite Anda.)


(Seperti biasa: ini adalah saran tentang pengoptimalan kinerja. Jadi, Anda harus mengukur dan memahami kinerja gim Anda sendiri, dan batasan apa yang Anda hadapi, sebelum menghabiskan usaha untuk menambahkan optimisasi.)


5
1 Untuk menyebutkan tentang tidak melakukan pemusnahan hanya demi itu, tetapi ketika diperlukan untuk masalah kinerja.
Will Marcouiller

12
+1 akhirnya memberi tahu saya bahwa sprite sheet memang memiliki alasan untuk ada selain untuk kenyamanan programmer / perancang
Bill

3
+1 untuk penjelasan yang bagus, saya belajar banyak dari jawaban Anda.
Jesse Emond

1
Tautan ke pdf "Batch, Batch, Batch" rusak. Berikut ini yang diperbarui: ce.u-sys.org/Veranstaltungen/…
Marton

13

Menurut sebuah posting di forum di MSDN, kerangka kerja XNA tidak melakukan pemusnahan frustrasi:

Kerangka XNA tidak akan melakukan pemusnahan frustrasi untuk Anda - itu tidak bisa karena tidak memiliki petunjuk di mana sesuatu akan benar-benar berakhir. Semua transformasi dilakukan pada GPU dan bisa menjadi kustom shader.

http://xboxforums.create.msdn.com/forums/p/22763/121897.aspx

Posting ini selanjutnya mengatakan, bahwa jika Anda memiliki banyak objek dalam adegan Anda, mungkin layak untuk Anda buat sendiri.


6
Terutama jika Anda memiliki peta gulir (Anda mengatakan itu 2D, jadi ini mungkin relevan). Ini hanya akan sia-sia jika Anda menggambar bagian besar yang tidak diperlukan. Ini tidak terlalu sulit dan Anda mungkin melihat semacam peningkatan.
Michael Coleman

1

Saya telah mengembangkan mesin teralis voxel prosedural selama beberapa tahun sekarang di XNA. Di sebagian besar frame, mesin mengubah ratusan ribu paha depan. Dalam profiling saya, saya telah menemukan bahwa frustum dan penyumbatan oklusi membuat peningkatan kinerja.

Profil XNA HiDef (bukan Reach) memiliki kelas OcclusionQuery yang digunakan untuk melakukan Occlusion Culling. Penyisihan Culling menghapus paha depan tersebut dari viewport yang disembunyikan dari tampilan paha depan lainnya.

Hal lain yang harus Anda pertimbangkan adalah memunculkan generasi dan tesselation secara terpisah.

Jadi ya, ketika Anda mendekati sejumlah besar paha depan di setiap frame yang sedang ditransformasikan, Anda perlu berpikir hati-hati bagaimana Anda dapat menerapkan teknik culling dan threading untuk mempertahankan laju frame, dengan mengurangi lalu lintas ke gpu shaders.

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.