Çok sayıda görüntüm nedeniyle veya bunlara rağmen sprite sayfaları kullanmalı mıyım?


13

Bir 2D oyun geliştiriyorum ve çok fazla sprite var. 2D'ye dönüştürmek için 3D animasyonlar ve modeller kullandım ve onlara "Fallout" ya da "Diablo" ifadelerini gördüm. Elle çizmekten daha kolaydır, lol.

Çerçeveyi 15 fps'ye kadar kesmek zorunda kaldım, bu da onlara dalgalı bir görünüm vermeden düşebileceğim en düşük seviyeydi. Ancak, 24 karenin inanılmaz derecede pürüzsüz görünmesinden dolayı üzgündü.

Bunu yapmamın iki nedeni var:

1) HDD alanını azaltın. Görüntüler ne kadar az olursa, toplam oyunum o kadar küçük olacaktır.

2) RAM tüketimini azaltın. Yüklenecek görüntü sayısı ne kadar az olursa, RAM sınırlamamı şişkinlikten kaçınmam daha olasıdır.

Ancak, hem HDD alanında hem de RAM'de görüntüleri sıkıştırmanın bir yolu olsaydı, bunu yapardım. Daha önce test ettim ve çoğu RGBA8888'den RGBA5555'e verirken kalitede herhangi bir değişiklik almıyor ve TexturePacker programımda RGBA4444'e dönüştürürken sadece küçük bir hit. Şu anda bunu yapmıyorum, çünkü SFML, hangi tip .PNG görüntüsüne bakılmaksızın aynı miktarda bellek kullanıyor gibi görünüyor. Nasıl farklı yükleneceğini araştırdım, ancak konuyla ilgili bir şey bulamadım.

2D video oyunlarının nasıl ele alınacağı hakkında çok şey okudum. Fikir birliği ezici: Mükemmel performans için Spritelarınızı Daha Büyük Bir Dokuya Paketleyin! Bu yüzden küçük spritelarımı TexturePacker kullanarak çok daha büyük bir sprite sayfasına paketledim.

Ancak, karakter başına 10-15 animasyon, hareket etmek için 5 yön ve animasyon başına 15-40 kare (muhtemelen ortalama 24) olmasını planlıyorum. 15 animasyon, 5 yön ve animasyon başına ortalama 24 kare ile; Bu karakter başına 1800 ayrı karedir. Sprite sayfasına yerleştirilmişse, bunun yerine yalnızca 75 resim olur. (Her Yön için Animasyon başına bir hareketli grafik sayfası. 15 * 5)

Oyundaki en büyük patron karakteri için spritesheet kullanamıyorum ve her seferinde tek bir görüntü yüklemek için bir yol programlamak zorundayım. Bunu henüz performans için yapıp yapamayacağımı bilmiyorum.

Karakterler için, bunları bir spritesheet'te zaten paketledim. Yürürken tek bir karakter için, bazen dursa da, çoğu zaman işe yarıyor gibi görünüyor. Ancak, bu karakter için tüm dokuları önceden yüklemek yerine dokuları değiştiren kötü tasarlanmış koduma bağlıyorum.

Dokular önceden yüklenecek olsaydı, sprite sayfaları için mantıklı. Her karakter için 1800 küçük resim önceden yüklemenin kötü bir fikir olduğunu hayal edebiliyorum.

Ancak, onları bir kerede bir bellek içine ve dışına aktarmak son derece hızlı olacağını düşünüyorum, bu yüzden bir seferde sadece tek bir görüntü bellek gerekir. Bu, herhangi bir anda her karakterin 45 + MB yerine yalnızca birkaç KB tüketeceği anlamına gelmez mi?

Akışın inanılmaz derecede hızlı olması gerektiğinden (saniyede 15 görüntünün bellek ve işleme girip çıkması gerektiğinden) performansımı öldüreceğini düşünüyorum ve görüntüler çok küçük olsa da, karakter sprite sayfaları yüklemek daha iyi bir fikir olabilir yerine hafızaya. Ama yine de daha büyük patron karakterim için tek görüntü akışı benzeri bir render sistemi kodlamak zorunda kalacak.

Deniyorum ama basit bir süreç değil. Özellikle oyun motorunun şu anda grafiklerle ilgilenmeyen diğer kısımları üzerinde çalıştığım göz önüne alındığında.


1. RAM veya HDD kısıtlamalarınızı belirtmediniz. Hızlı erişim için kaç karakterin olması gerekir? 2. Metin boyunca birkaç soru vardır, belki onları cesurca odaklayabilir, hatta soruları bölümlere ayırabilirsiniz?
Kromster

Üzgünüm. Çok değil. Herhangi bir anda ekranda maksimum bireysel karakter sayısının yaklaşık 40 olacağını düşünürüm. Eğer insanlar müşterilerini çökertmek için bir noktaya işaret ettiyse, o zaman ... 130 mutlak maks. Tipik olarak, tipik maksimum için sadece 10 olması gerekir ve mutlak maksimum <40'tan fazla olmaz. 40'ın üstündeki herhangi bir şey aşırı, çok nadirdir, kullanıcılar ekran görüntüsü dışında herhangi bir nedenden dolayı veya karakterlerde tıkınma eğlencesi için karakterleri bilerek sıkıştırmaya çalışırlar. 10'un üstündeki herhangi bir şey nadirdir ve yaklaşık 40 olan herhangi bir şey son derece nadirdir.
Carter81

Oyun sadece PC (mobil yok) 2D rpg, ancak ben sadece mümkün değilse bir mobil platform dışlamak istemiyorum. Sahip olduğum RAM alanının, kullanıcının bilgisayarında ve kullanıcının VRAM'ında bulunan RAM ile sınırlı olduğunu düşünüyorum. Çok büyük bir HDD akıllıca olacağından şüpheliyim. HDD tüketimi için ne kadar küçükse o kadar iyi olur.
Carter81

Ekranda kaç tane BENZERSİZ karaktere ihtiyacınız var?
Kromster

20'den fazla değil. Yukarıdaki herhangi bir şey, aldatmadıkça imkansız olacaktır. Genellikle 5-10.
Carter81

Yanıtlar:


16

RTS Remake ile benzer bir vakamız var. Tüm birimler ve evler sprite. Birimler ve evler ve arazi için 18.000 sprite, ayrıca takım renkleri için başka bir ~ 6.000 sprite (maske olarak uygulanır) var. Uzun gergin ayrıca yazı tiplerinde kullanılan yaklaşık ~ 30.000 karakter var.

Atlasların arkasındaki ana sebep:

  • daha az boşa RAM (NPOT'u GPU'ya yüklediğinizde daha eski günlerde POT'a uzattı / doldurdu, hala iOS ve bazı çerçevelerle aynı olduğunu okudum. Hedeflediğiniz donanım aralığını daha iyi kontrol edebilirsiniz)
  • daha az doku anahtarları
  • daha az sayıda büyük parçaya daha hızlı yükleme

Bizim için ne işe yaramadı:

  • paletlenmiş dokular. Bu özellik yalnızca OpenGL 1.x 2.x'te mevcuttu ve o zaman bile çoğunlukla GPU üreticileri tarafından bırakıldı. Ancak OpenGL + Shaders'ı hedeflerseniz, gölgelendiricilerde kendinizi iyi kodlayabilirsiniz!
  • NPOT dokuları, piksel sanatında kabul edilemez olan yanlış sınırlar ve bulanık spritelarla ilgili sorunlarımız vardı. RAM kullanımı da çok daha yüksekti.

Şimdi her şeyimiz onlarca 1024x1024 atlas (modern GPU'lar daha büyük boyutları destekliyor) paketlenmiş ve bu sadece bir PC oyunu için oldukça iyi olan sadece ~ 300mb bellek yemek iyi çalışıyor. Yaptığımız bazı optimizasyonlar:

  • RGBA8 (dama tahtası gölgeleri) yerine RGB5_A1 kullanmak için kullanıcı seçeneği ekleyin
  • mümkünse 8 bit Alfa kullanmaktan kaçının ve RGB5_A1 biçimini kullanın
  • spriteları atlaslara sıkıca paketleyin (bakınız Kutu Paketleme algoritmaları)
  • her şeyi HDD'den bir yığın halinde saklayın ve yükleyin (kaynak dosyaları çevrimdışı oluşturulmalıdır)
  • donanım sıkıştırma biçimlerini de deneyebilirsiniz (DXT, S3TC, vb.)

Mobil cihazlara taşınmayı ciddi olarak düşündüğünüzde kısıtlamalar konusunda endişeleneceksiniz. Şimdilik sadece oyunu çalıştırın ve oyuncuları çekin! ;)


Bu şimdiye kadarki en iyi çözümdü! Spritelarım RGB5_A1 veya RGBA4444'te bile farklı görünmüyor, ancak bellekte tasarruf sağlıyor. RAM'deki ve VRAM'deki tüm öğelerimi önceden yüklemek için sohbetteki bir öneriniz mükemmel. Dahası, RAM'e sahip olanlar için yüksek çözünürlüklü istemci veya kare hızını yarı yarıya azaltmak için bir seçenek gibi isteğe bağlı grafik düzeylerine sahip olmayı önerdiniz.
Carter81

5

Burada teğetsel olarak ilgili bir cevabım var , ancak genel fikir şu ki, farklı zamanlarda dokuları yüklüyorsanız ve çiziyorsanız (render yaparken ek dokular yüklemezseniz), o zaman yapmak performansınızı etkiler:

Yüklenme zamanı:

Bu, dokularınızı belleğe yüklediğiniz andır. Tüm Eğer VRAM gönderiyoruz veri miktarı çoğunlukla sizin yükleme süresi ne kadar süreceğini tanımlayacaktır budur. Dokularınızın RGBA4444 gibi daha küçük formatlara sahip olması bunu daha hızlı hale getirecektir. Bununla birlikte, VRAM'a yüzlerce megabaytlık doku yüklemezseniz, muhtemelen burada bir darboğaz yaşamayacaksınız. Bunu yaparsanız, güzel bir yükleme ekranı beklemeyi kolaylaştırabilir.

Dokularınızı atlaslara katmanın çok az etkisi olacaktır, çünkü VRAM'a gönderdiğiniz tüm bilgi miktarı aynı olacaktır. Aslında, dokularınızı atlasanız ve atlaslarınızda boş alanlar bırakmanız gerekiyorsa, o zaman aslında VRAM'a daha fazla veri göndereceksiniz ve bu nedenle bu kısım daha yavaş olacaktır!

Oluşturma performansı:

Tüm dokularınız VRAM'a girdikten sonra, sahip olduğunuz doku miktarı oluşturma performansını etkilemez. Görüntü oluşturma performansınızı etkileyen dört öğe vardır:

  1. İşleme durumu değişiklikleri : Oluşturmak istediğiniz görüntüyü her değiştirdiğinizde, görüntüyü oluşturmak için gereken süreyi ciddi şekilde artırır. Genel olarak, durum değişikliği miktarını en aza indirmek istersiniz ve art arda çizeceğiniz birkaç görüntüyü doku atlasında gruplandırarak durum değişikliği miktarını azaltabilirsiniz.

    Sadece atlas yapmak yeterli değil. Performans kazanımları elde etmek için atlasın durum değişikliklerinin azaltılacağı bir şekilde olması gerekir. Örneğin, bir karakterin ana karakterine sahip olmanın size bir performans kazancı sağlayacağını düşünebilirsiniz, ancak çerçeve başına bu hareketli grafik sayfasından yalnızca bir hareketli grafik çiziyorsanız, sahip olduğunuzdan daha fazla performans kazanmazsınız her hareketli grafik ayrı bir dosyada.

    Uygun atlaslama önemsiz değildir, ancak genel olarak spriteları aynı katmandan güvenle gruplayabilirsiniz. Örneğin, tüm GUI öğelerinin bir hareketli grafik sayfasında bulunması çok umut verici bir fikirdir, ancak canavarları alfabetik olarak gruplandırmak mümkün olmayabilir.

  2. Çizim aramaları: Genel olarak, çizim aramalarınızı minimumda tutmak isteyebilirsiniz. Önemli bir kural, iki çizim çağrısı arasında render durumu değişikliği yoksa, bunları tek bir çizim çağrısına katılabilmenizdir. Daha gelişmiş performans kazanımları için, 8 doku örneği ve 8 çizim için grup çizim çağrısı kullanabilirsiniz, böylece her 8 dokuda sadece dokuları değiştirmeniz gerekir.

  3. Üçgen sayısı: Aslında, ne kadar çok üçgen çizerseniz, onları çizmeniz o kadar uzun sürer. Ancak, modern bilgisayarlarda ve çoğu 2D oyun için, bunu en üst düzeye çıkarmaktan çok uzak olacaksınız. Her kare için yüz binlerce sprite güvenle çizebilir ve yine de çılgınca iyi çerçeveler elde edebilirsiniz. GPU'nuzla ilgili sorun yaşamadan aşırı miktarda sprite çekiyorsanız, muhtemelen daha fazla CPU'ya bağlı olacaksınız.

  4. API ayarları: Her şeyi doğru yapıyorsanız ve hala garip bir şekilde düşük kare hızı alıyorsanız, spritelarınızı çizdiğiniz ayarları kontrol edin. SFML'yi bilmiyorum, ancak örneğin Direct3D 9'da D3DUSAGE_DYNAMIC, veya ile bir köşe tamponu oluşturma D3DPOOL_MANAGED, oluşturma sürelerinizi on katına kadar artırabilir. Tabii ki, vSync kullanmak kare hızınızı monitörünüzün yenileme hızında kaplar. Ayrıca, hizalanmamış FVF'lerin kullanılması bazı GPU'lardaki performansı düşürebilir. Bu da Direct3D 9 içindir.

    Sizin durumunuzda, kullandığınız API'nın belgelerine bakın.

Yalnızca düşük ila orta miktarda (1 GB'tan az) dokuya sahipseniz ve düşük miktarda sprite (çerçeve başına bir milyondan az) çiziyorsanız, ilk bakacağım API ayarlarını değiştirmek ve ardından oluşturma durumlarının azaltılması ve çağrıların çizilmesi.


Yükleme sürelerini umursamıyorsam, RAM veya VRAM tükenmezse, her şeyi önceden belleğe yüklemem gerektiğini varsaymak mıyım?
Carter81

Ben sadece her şeyle ilgileniyorum ÇÜNKÜ RAM / VRAM'da zayıflamaktan korkuyorum. Nedenini bilmiyorum, ancak oyunumu oynayan kullanıcıların çok fazla benzersiz sprite içeren bir alana yüklemeye çalıştıklarında veya ekranlarına çok fazla karakter girdiğinde çökeceklerini taşlıyor. Yanılmıyorsam ve her bir hareketli grafik 96KB tüketiyorsa, her benzersiz karakter 15 animasyon, 5 yön ve animasyon başına ortalama 24 kare içeriyorsa, tam olarak yüklenen her bir karakter 173 MB'dir. Ekranda aynı anda 10, hatta daha fazla benzersiz karakter olabilir.
Carter81

@KromStern: Atlasınız varsa ve boş alanlar (dolgu) bırakmanız gerekiyorsa, veriler daha büyük olacaktır ve bu nedenle yükleme süreleri daha uzun olacaktır. Daha uzun yükleme sürelerinin nedeninin boş alan olduğu ve toplam yükleme süresinin doku miktarıyla değil, toplam veri miktarıyla ilgili olduğu açıktır. Orada yanıltıcı bir şey görmüyorum ve bence orijinal soruyu anlamak için yeterli bilgiye sahip bir kişi, dokulara ve atlaslara PoT ve nPoT olduğunda tüm durumlar için noktalara katılabilecek ve kendi sonuçlarını çıkarabilecektir.
Panda Pijama

1
@ Carter81: "i5, 1gb RAM, NVidia GT260, 400mb hdd" gibi hedef donanım yapılandırmanızı seçmeniz ve bundan çalışmanız gerekir. Her zaman daha zayıf ve daha az RAM'e sahip PC'ler olacaktır.
Kromster

Açıkçası, herhangi bir zamanda 15 animasyona ihtiyaç duymazlar. Bununla birlikte, 10 benzersiz karakterin tümü aynı anda "Savaş Modu" na girerse ve bu nedenle 5 animasyonla (yürüme, koşma, boşta, dövüşsüz vb.) 5 setle (savaş yürüyüşü, boşta mücadele, savaş vb.)? SFML ile yapmayı denediğimde doku atlaslarını değiştirirken istemcinin belirgin bir donması veya duraklaması yarattığı için dokuları değiştirmekten korkuyorum . Bu kadar çok sprite için çeşitli stratejilerle darboğazımın ne olacağını bilmiyorum.
Carter81
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.