Bir XNA 2D oyununu optimize etme


56

Görüntü oluşturma dışındaki nesneleri görüntüleme alanının dışına atlamak için mantığın uygulanması mantıklı geliyor mu yoksa bunu umursamalı mıyım ve Çerçeve yapsın mı?

Yanıtlar:


79

Temizleme, performans iyileştirmesidir. Bu yüzden sadece onun uğruna yapmak sadece mantıklı değil. Bir sebebin olmalı.


GPU (XNA Çerçevesi değil), üçgenleri ve pikselleri kör bir şekilde hızlı bir hızda çıkarır. Gönderdiğiniz her üçgen dönüştürülmelidir (köşe gölgelendiriciniz aracılığıyla). Sonra ekrandan inenleri çıkarır. Sonra kalan üçgenleri doldurur, ekran dışı pikselleri toplar. Kalan pikseller daha sonra arka tampona çekilir (piksel gölgelendiriciniz aracılığıyla).

(Ben "o zaman" dediğimde - aslında tüm bunları büyük ölçüde paralel bir boru hattında yapıyor.)

Bu yüzden bireysel üçgenleri temizlemek zorunda kalabileceğiniz çok nadir ve sıradışı bir durumdur. Köşe sınırlarını aşmak için, çok fazla sayıda üçgen çiziyor olmanız gerekir. Doldurma oranı, doku alma veya piksel gölgeleme sınırlarına ulaşmak için, genellikle yüksek bir derinlik karmaşıklığına sahip olmanız gerekir (bu durumda görünüm penceresi / frustum ayırma işleminin yardımı olmaz).


Bu yüzden genellikle ekran dışı geometriye sahip olmanın maliyeti çok az veya hiç yoktur.

Maliyet - özellikle "nesneler" (genellikle 3B nesneler) çizilmesi bağlamında - aslında bu nesneleri ilk etapta GPU'ya sunmaktan kaynaklanıyor . Çok fazla nesne gönderin ve parti limitinizi yükseltin ( kare başına birkaç bin * parti olsun ).

Bu yanıtı ve bu bağlantılı slayt desteğini , yığınların ayrıntılı bir açıklaması için okumanızı öneririm .

Bu nedenle, eğer sıkıntı çekmeden uygularsanız, GPU’ya gönderdiğiniz parti sayısını azaltabilirsiniz. Parti sınırlıysanız - bu sizi sınırın altına alabilir.


Şimdi - sorunuz 2D XNA ile ilgili - bu yüzden muhtemelen kullanıyorsunuz SpriteBatch. Bu biraz farklı.

Buna "Sprite Batch " denilmesi yanlış değildir . Yaptığı şey, çizdiğiniz spritleri almak ve bu spritleri GPU'ya göndermek için mümkün olan en az sayıda grubu bir araya getirerek mümkün olan en az işlemi yapmaktır .

Ancak SpriteBatch, aşağıdaki durumlarda yeni bir toplu iş başlatmak zorunda kalır:

  • Tek bir partiye sığabileceğinden daha fazla sprite çizersin (XNA 4'te 2048 sprite)
  • Dokuyu değiştirirsiniz (bu yüzden bir dokuya göre sıralama seçeneği vardır)

Öyleyse, birincisine giriyorsanız ayıklama uygun bir optimizasyondur. Çok fazla partiyle sonuçlanacak kadar çok sayıda sprite gönderiyorsanız (muhtemelen bant genişliğini de kullanıyorsunuzdur - ama kesinlikle önce parti limitine varacağınızdan eminim). Bu, ancak yalnızca gerçekten muazzam bir dünyaya sahipseniz gerçekleşir - bu nedenle, bu durumda genellikle çok basit, hızlı ama yanlış bir iticiliği ortadan kaldırabilirsiniz.

Şimdi - sizi parti sınırını aşmak için yeterli doku değişimiyle çizim yapıyorsanız ve bunların çoğu aslında ekran dışıysa ve onları ayırmak sizi parti sınırının altına alır. O zaman evet - temizleme, işe yarayacak bir optimizasyondur.

Bununla birlikte - bu durumda izlenecek daha iyi bir optimizasyon, doku atlaslarının (aka: sprite levhaları) kullanılmasıdır. Bu , ekranda veya kapalı ekranda ne olduğuna bakılmaksızın doku değiştirme ve dolayısıyla grup sayısını azaltmanıza olanak tanır . (Bu, spritelarınız için bir kaynak dikdörtgen belirtmenizin ana nedenidir.)


(Her zaman olduğu gibi: bu performans optimizasyonu için bir öneridir. Bu nedenle, optimizasyon eklemek için çaba harcamadan önce oyunun kendi performansını ve hangi limitleri attığınızı ölçmeli ve anlamalısınız.)


5
+1 Sadece bunun uğruna değil, performans açısından gerekli olduğunda bununla ilgili bir şey yapmamaktan bahsettiğim için.
Marcouiller

12
Sonunda sprite levhalarının gerçekten de programcı / tasarımcı rahatlığı dışında bir nedeni olduğunu söylediği için +1
Bill

3
Büyük açıklama için +1, cevabınızdan çok şey öğrendim.
Jesse Emond

1
"Toplu, Toplu, Toplu" pdf bağlantısı koptu. İşte güncellenmiş bir tane: ce.u-sys.org/Veranstaltungen/…
Marton

13

MSDN'deki forumlarda yayınlanan bir yayına göre, XNA çerçevesi sıkıntı yaratmıyor:

XNA çerçevesi sizin için hiçbir sıkıntı yaratmayacak - bir şeyin gerçekte nerede biteceği konusunda hiçbir fikrinin bulunmadığı sonucuna varamadı. Tüm dönüşümler GPU'da yapılır ve özel bir gölgelendirici olabilir.

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

Bu gönderi, sahnenizde çok fazla nesne varsa, kendinizin çekmeye değer olabileceğini söylemeye devam ediyor.


6
Özellikle kayan bir haritanız varsa (2B olduğunu söylediniz, bu yüzden bu alakalı olabilir). İhtiyacı olmayan büyük bölümler çizerseniz bu sadece bir israftır. Çok zor değil ve bir çeşit iyileşme görebilirsiniz.
Michael Coleman

1

XNA'da birkaç yıldan beri işlemsel voksel arazi motorları geliştiriyorum. Çoğu çerçevede, motorlar tam anlamıyla yüz binlerce dörtlü dönüştürüyorlar. Profillerimde, frustum ve oklüzyon temizleme işleminin performansı artırdığını gördüm.

XNA HiDef profili (Reach değil), Occlusion Culling gerçekleştirmek için kullanılan bir OcclusionQuery sınıfına sahiptir. Tıkanma Ayırma, bu dörtlüleri, diğer dörtlüler tarafından görünmeyle gizlenmiş olan bir görünüm penceresinden kaldırır.

Göz önünde bulundurmanız gereken başka bir şey, hem nesli hem de tezi ayrı ayrı anlatmaktır.

Bu yüzden evet, dönüştürülen her karede çok fazla dörtlü dörtlüe yaklaştığınızda, kare oranını korumak için takma ve geçirme tekniklerini nasıl uygulayabileceğinizi, gpu gölgelendiricilere giden trafiği azaltarak nasıl dikkatlice uygulayabileceğinizi dikkatlice düşünmeniz gerekir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.