Hızla bulanıklaşan spritelar


9

Oyunuma hız ekledikten sonra, dokularımın seğirdiğini hissediyorum. Sonunda bir ekran görüntüsünde yakalayana kadar bunun sadece gözlerim olduğunu düşündüm:

resim açıklamasını buraya girin

Soldaki oyunumda ortaya çıkan şey; sağdaki yapıştırılan orijinal hareketli grafiktir. (Bu, Photoshop'un 6x yakınlaştırılmış bir ekran görüntüsüdür.)

Kenarların takma adı olduğuna dikkat edin - neredeyse alt piksel oluşturmaya benziyor. Aslında, spritelarımı (konum ve hızları ints olarak) tamsayı değerleri kullanarak çizmeye zorlamasaydım, MonoGame'in kayan nokta değerleri ile çizim yaptığına yemin ederim. Ama değil.

Bu tür şeylerin bulanık görünmesinin nedeni ne olabilir? Hız uygulanmadan gerçekleşmez.

Kesin olmak gerekirse, SpriteComponentsınıfımın bir Vector2 Positionalanı var. Ben çağırdığınızda Draw, ben aslında kullanmak new Vector2((int)Math.Round(this.Position.X), (int)Math.Round(this.Position.Y))pozisyon için.

Daha önce sabit nesnelerin bile titremesi gereken bir hata vardı - bu, düz Positionvektörü kullanarak ve değerleri yuvarlamamdan kaynaklanıyordu ints. Eğer yuvarlak yerine Floor/ Ceilingkullanırsam, hareketli grafik / asılı durur (her iki yönde bir piksel farkı) ama yine de bulanıklaşır.


1
Bu, uygulanan doku filtrelemesi ile ilgili olabilir mi?
OriginalDaemon

Gölgelendiricinizin kodu var mı? Bazı insanlar pikselleri ortalamak için her iki eksene yarım piksel ekler. Ama emin değilim, bence bu sadece bir DirectX.
William Mariager

3
Filtrelemeyi devre dışı bırakmak bir çözüm değil, geçici bir çözümdür.
Archy

1
Oluşturma hızınız hakkında hiçbir şey bilmiyor, bu nedenle konum, boyut veya SpriteBatch.Draw'a verdiğiniz geçiş başka bir şey değil ya da hız eklemeden önce hata vardı. SpriteBatch.Draw'ı tam olarak nasıl çağırıyorsunuz?
Archy

1
@ ashes999 Bu çağrıda hata ayıkladınız ve bunu kontrol ettiniz. X, this.Y ve this.origin? Bu nedir. Orjin nedir? Bu Draw çağrısı aynı olduğunda, oluşturma sonucunun temel olarak hiçbir yolu yoktur.
Archy

Yanıtlar:


3

Bu utanç verici.

Görünen o ki tamsayı pozisyonları değil, float pozisyonları kullanarak çizim yapıyordum. Archy yorumu ile beni doğru yola doğrulttu@ashes999 did you debug this call and checked this.X, this.Y and this.origin?

Bir izleme ifadesi ekler eklemez, hiçbir şeyin izlenmediğini fark ettim. SpriteComponentSınıfımın tamsayı değerlerini doğru bir şekilde kullandığı ortaya çıktı , ancak SpriteSheetComponentyine de hamdan gelen float değerlerini kullandım Vector2 Position.

Doku filtrelemeyi ve kelepçelemeyi denememe rağmen, bunların doğru değişiklik olmadığından şüpheliydim, çünkü kaynak görüntü ile aynı genişlik ve yükseklikte bir 2D görüntü çiziyordum (ölçeklendirme yok).


1
Bitti, bulduğuna sevindim!
Archy

2

XNA, konumu olarak pikselin merkezini kullanan DirectX9 kullanır. Bu, draw sınıfının Vector2 tabanlı aşırı yüklerini kullanırken fark edilir. Çıkarmanın (.5, .5) sorununuzu çözmesi gerektiğine inanıyorum.

Daha fazla bilgi burada.


Bunu teknik olarak yapamam, çünkü int, intargüman olarak bir Vector2 geçiyorum . Bunun yanı sıra, hareket eden herhangi bir nesnem olmadığında işler mükemmel görünüyor.
ashes999

Nesne hareket halinde olduğunda ne demek istiyorsun? XNA'nın hareket kavramı yoktur, sizin de söylediğiniz yere çeker. Onun sabit anlık görüntüleri bir dizi. Yine de bir dikdörtgene yuvarladığınız için Dikdörtgen aşırı yüklenmelerini kullanmayı deneyin.
ClassicThunder

Kendi hız uygulamam var. hıza bağlı olarak yüzer olarak artan SpriteComponentbir Vector2konuma sahiptir ; çizdiğimde, X ve Y'nin Vector2tamsayı (yuvarlatılmış) sürümleriyle yeni bir tane oluşturuyorum. positionBu sorun değil, çünkü hızı olmayan sabit nesneler iyi görünüyor.
ashes999

Yani p pozisyon vektörünüz ve v v hızınız olduğunu söylüyorsunuz, bunları p + = v gibi ekleyin, sonra yuvarlak değerleri kullanarak p'nin bir kopyasını oluşturun. Ve bu sarılık farklı değerlerin, çizim çağrıları aynı olmasına rağmen önceki p + = v ile aynı konuma sahip olduğunu mu? Çünkü bu hiç mantıklı değil.
ClassicThunder

Evet, @Archy de öyle diyor. Hata ayıklayayım ve tekrar kontrol edeyim. Ben p += vsırasında eklemek Updateve ile render new Vector2((int)Math.Round(p.X), (int)Math.Round(p.Y))).
ashes999

2

Oluşturma hızınız hakkında hiçbir şey bilmiyor, bu nedenle konum, boyut veya SpriteBatch.Draw'a verdiğiniz geçiş başka bir şey değil ya da hız eklemeden önce hata vardı. SpriteBatch.Draw'ı tam olarak nasıl çağırıyorsunuz?

Bu çağrıda hata ayıkladınız ve bunu kontrol ettiniz. X, this.Y ve this.origin? Bu nedir. Orjin nedir? Bu Draw çağrısı aynı olduğunda, temel olarak hız ile oluşturma sonucunun farklı bir yolu yoktur.


1

Sorun büyük olasılıkla doku filtrelemenin açık olması. Bunun ne anlama geldiğinden emin değilseniz, 2 piksel genişliğinde bir resminizin olduğu bir durumu düşünün: İlk piksel siyah, ikinci piksel beyazdır. Bu dokuyu yakınlaştırırsanız, doku filtreleme açıksa, bulanıklaştığını ve siyah beyaz piksel arasındaki alanın degrade gri renk kullandığını göreceksiniz.

Filtrelemeli ve filtrelemesiz oyunlara klasik bir örnek, Doom'da filtrelememiş olan Super Mario 64'tür.

Hızı kullanmadığınızda, Sprite'ınız muhtemelen doku merkezi XNA'nın (ya da altta yatan api'nin kullanıldığı) örnek noktasında olacak şekilde konumlandırılır. Bir yüzer hız ile hareket ettiğinizde, Sprite'ınızın konumu değişir, bu nedenle örnek noktası doğrudan bir pikselin merkezine hizalanmayabilir, bu nedenle sonuç, en yakın piksellerin ortalaması olan bir rengin işlemek için kullanılır.

Sprite öğenizi ekranda gerçekten büyük hale getirerek filtrelemenin açık olduğunu doğrulayabilirsiniz. Bulanıksa, sorun budur.

Oluşturma işleminde piksel mükemmel doğruluğa sahip olmanız gerekiyorsa, bir yerde saklanan konum için bir kayan nokta değerine sahip olmak isteyeceksiniz, ancak oluşturduğunuz nesnenin konumu için tamsayı değerleri kullanın ... veya elbette filtrelemeyi kapatabilirsiniz oyunun buna ihtiyacı yoksa.

Ayrıca okumak isteyebilirsiniz bu .


Sorumda belirttiğim gibi, bulunduğum yerde konumum ve orijinal görüntü boyutu için tamsayılar kullanıyorum Draw. Bunun nasıl olabileceğinden emin değilim - ancak büyük ölçekli oluşturmayı ve doku filtrelemeyi kapatmanın yardımcı olup olmayacağını görmeyi deneyeceğim.
ashes999

1

SpriteBatch.Begin çağrısında SamplerState'inizi SamplerState.PointClamp olarak ayarlamayı deneyin.

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.