XNA'da Büyük Arazi Oluşturmanın Etkin Yöntemi


10

Oyuncular için büyük bir alan gerektiren bir XNA oyunu oluşturuyorum. Şu anda, kullandığım test yükseklik haritası 4096x4096 ve 4 bit BMP olarak kaydedildi.

Yapmaya çalıştığım şey o büyük heightmap dosyasını alıp oyunda işlemek. Karşılaştığım sorun, mevcut belleğin çoğunu kullanacağı için tüm araziyi bir kerede belleğe yüklemenin verimsiz olmasıdır.

Karşılaştığım bir başka sorun da, XNA'da ayarlanan bir sabit sınır nedeniyle araziyi bir ilkel olarak oluşturamayacağım.

Bununla birlikte, aşağıda listelediğim bir dizi çözümle karşılaştım:

  • Geçerli kullanıcının konumuna göre oluşturma - temel olarak dünyadaki yönleri ne olursa olsun kullanıcının çevresine bir kare çizme. Bu da tam olarak istediğim şey değil, çünkü hala kullanıcının görmediği alanı oluşturuyorsunuz.
  • Kullanıcının yönüne ve konumuna göre oluşturma - Yükseklik haritasının hangi piksellerinin oluşturulması gerekiyordu, ancak bunun çok zor olduğu bir üçgen elde etmek için bir formül buldum.
  • Araziyi birden çok parçaya bölme ve hangisinin kullanıcıya en yakın olduğunu oluşturma - Hala insanların görmeyeceği parçaları oluşturduğunuz için hala çok verimli değil. Ve yoğun iş gerektiriyor çünkü yükseklik haritamı birkaç parçaya ayırmam gerekiyor ve ölçeklenebilirlik büyük bir sorun haline geliyor.

Bu çözümleri denedikten sonra, ne yapacağım konusunda yeni fikirlerim var. İnsanların bana bu karmaşık algoritmaları yapmamı söylediği bazı cevaplar aldım, ancak bunları nasıl yapacağımı bile bilmiyorum.

Bu yüzden temelde XNA'da mizahi arazileri en yüksek verimlilikle oluşturmanın basit, basit bir yolunu istiyorum.

Genel olarak oyun geliştirme konusunda yeniyim, ancak umut verici görünüyorsa araştırmaya hazırım.

Güncelleme 1: Geoclipmapping yöntemini araştırdıktan sonra kodlamaya başladım. Tüm matematiği yaptım ve oyun çalışıyor. Ancak, son derece verimsiz - bu muhtemelen benim için kötü kodlama. 2FPS'de çalışır ve CPU'mun tam bir çekirdeğini kullanır. Ben kodu geliştirmeye çalışacağım, ama daha fazla yardıma ihtiyacım olacağını düşünüyorum, bu yüzden burada Terrain manager sınıfı için kodun bir Pastebin olduğunu . Daha verimli olabilmem için daha sonra daha fazla sonuç göndereceğim.


1
İlginç bir şekilde, bahsettiğiniz teknik, ID Software'in yaklaşan oyunu Rage'de kullandığı tekniğe benziyor. Bir 'megatexture' kullanırlar ve sonra gerekli olan parçaları GPU'ya aktarırlar. Bu konuda bir konuşma yaptı, ancak bir wikipedia makalesi heres, ilham verici olabilir: en.wikipedia.org/wiki/MegaTexture

Yanıtlar:


5

Parçalar yaklaşımı tipik olarak kullanılır. Nadiren, her üçgeni yüzbinlerden her birini test etmeniz gerekip gerekmediğini görmek için test etmek verimli olur. Bunun yerine çoğu arazi oluşturma algoritması , arazinin görünür kısımlarını dinamik olarak oluşturmak için bir uzamsal veri yapısı kullanır .

Uygulaması kolay bir veri yapısına dörtlü denir . Kısacası, bir quadtree kullanmak için oyuncunun görüntüleme frustumunu bulur, quadtree'nin en üst seviyesiyle kesişir ve kısmen görüntülenebilir parçalar (yani, frustum uçakları parçaya keser) ve tüm çocukları test edersiniz parçalar, frustum dışındakileri atlıyor. Bu, gerçek görünür geometriye sadece birkaç tekrarlama seviyesi ile oldukça yakın bir yaklaşım verecektir.

Daha gelişmiş arazi oluşturucuları yalnızca görüntülenebilir geometriyi değil, aynı zamanda bu geometrinin ayrıntılarını da ayarlamak için bir algoritma kullanır. Geomipmapping (ve göreceli geoclipmapping) şu an için nispeten popülerdir, ancak uygulanması önemsiz bir şey değildir.

edit: İşte hem geoclipmapping hem de frustum culling iyi bir açıklaması.

Ayrıca, sonuçta çok fazla düzeltme yapmazsanız, yükseklik haritası için 4 bitin gerçekten güzel bir arazi üretmek için yeterli olup olmadığı konusunda bazı şüphelerim var.


Bu makaleye bir göz attım ve ilk önce geoclipmapping yöntemiyle gideceğime karar verdim, çünkü çok fazla araziyi sergilemede en verimli gibi görünüyor. Sonuçlarımla geri göndereceğim.

3

GPU'ya veri yüklemek için çerçeve başına çalışma yapmanızı gerektiren herhangi bir yaklaşım kusurlu olacaktır.

İşte iyi performans göstermesi gereken bir yaklaşımın kabaca özeti:

Arazinizi (oldukça büyük) parçalara bölmelisiniz, bu parçaları sabit köşe tamponlarına yüklüyor olmalısınız (yükseklik haritanızın bit derinliği önemli değil!). Bu köşe arabellekleri, oluşturulmayı bekleyen GPU belleğinde basitçe oturur. Uygun bir yığın boyutu olanı denemeniz gerekir, ancak 128x128 belki de başlamak için iyi bir yerdir.

4096x4096 arazi için, GPU'ya bir kerede rahatça yükleyebileceğim sınırın biraz ötesindesiniz - muhtemelen birkaç yüz MB köşe verisi (her ne kadar isterseniz ~ 64 MB akıllı). Bu nedenle, arka planda GPU'dan köşe arabelleklerini yüklemeniz ve boşaltmanız gerekebilir.

(Parçaların arka plan yüklemesini uygularsanız, bu son derece ölçeklenebilir olmalıdır!)

GPU'da köşe verileri elde edildikten sonra , yığın başına görünürlük ayıklaması yapmak için uygun bir zamandır . Kameranın arkasında olduğunu biliyorsanız, bir yığın oluşturmak için komut göndermenize gerek yoktur.

İşlemcide neredeyse hiç üçgen başına culling yapmamalısınız !

GPU, ekran dışında kalan üçgenleri yapabileceğinizden çok daha hızlı bir şekilde kaldıracaktır .

Performans hakkında daha fazla bilgi için Game Dev sitesindeki bu cevaba göz atın .


0

Ben hiçbir şekilde XNA bir uzman değilim, bu yüzden lütfen yanılıyorsanız beni düzeltin ama aslında böyle durumlar için optimizasyon yerleşik olduğu izlenimi altındaydı. Bir render mesafesi ayarlayabildiğinizi biliyorum ve bu noktadan sonra hiçbir şey yapmaz, sizin durumunuzda kalan arazi olacaktır. Ancak bu, işlenmiş dünyanız için oldukça çekici olmayan bir avantaj sağlar, bu nedenle çoğu açık dünya oyununun sahip olduğu sisleme gibi bir şey uygulamanız gerekir.


Yerleşik çözümler var, ancak karşılaştığım sorun, ilkel için çokgenler üzerindeki sınırı aşan büyük bir ilkel oluşturmaya çalışıyordum. Bu nedenle, çizmez, sadece bir istisna atar.
sammarks
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.