Sprite sayfası dokuları bitişik doku kenarlarını alarak


10

Basit bir hareketli grafik sayfası kullanan özel bir hareketli grafik (openGL 2.0) var (dokularım yan yana yatay olarak düzenlenmiş).

Örneğin, 2 basit dokuya sahip bir test sprite sayfası:

resim açıklamasını buraya girin

Şimdi, openGL sprite nesnesimi oluştururken yaptığım şey, atlasındaki toplam kare sayısını belirtmek ve çizerken, çizmek istediğim kareyi belirtmektir.

Daha sonra dokuyu nereden yakalayacağınız işe yarar:

Gerekli kare sayısının toplam kare sayısına bölünmesi (sol koordinatı almak için)

Ve sonra toplam kare sayısına göre 1'e dalın ve sonucu yukarıda hesaplanan sol koordinatlara ekleyin.

Bu işe yarıyor gibi görünüyor ama bazen sorun yaşıyorum. Mesela, aşağıdaki X'i çizmek istiyorum ve ...........

resim açıklamasını buraya girin

Her doku arasına 1 piksellik bir 'dolgu' koymayı duydum ama birisi bunun tam olarak nasıl çalıştığını açıklayabilir mi? Yani bunu yaparsam, kesinlikle doku elde etmek için hesaplamaları atar.

Dolguyu toplanan dokuya dahil edersem (böylece sprite boş bir kenarlıkla çizilir), o zaman kesinlikle bu çarpışma tespiti ile ilgili soruna neden olur mu? (örn. saydam parçalar çarpıştığında sınırlayıcı kutular kullanılırken spritelar çarpışıyor gibi görünebilir).

Birisi açıklayabilir eğer takdir ediyorum.


Kullandığınız GL_NEARESTveya GL_LINEARdoku oluşturma için?
MichaelHouse

GL_Linear @ Byte56
BungleBonce

Yanıtlar:


16

Doku atlasları ve sızan bitişik metinlerin kullanımıyla ilgili problem, doğrusal doku filtrelemenin çalışmasıyla ilgilidir.

Dokunun tam olarak bir dokunun merkezinde örneklenmemiş herhangi bir nokta için, doğrusal örnekleme 4 bitişik dokuyu örnekleyecek ve sorduğunuz konumdaki değeri (örnek noktasından uzaklığa göre) ortalama 4 olarak hesaplayacaktır. örnekleri.

İşte sorunun güzel bir görselleştirmesi:

  

Gibi bir şey kullanamadığınız için GL_CLAMP_TO_EDGEDoku atlasında olduğu bir için, her bir dokunun kenarı etrafında kenarlık metinleri oluşturmanız gerekir. Bu kenarlık dokuları, atlastaki tamamen farklı dokulardaki komşu örneklerin, yukarıda açıklanan ağırlıklı enterpolasyon yoluyla görüntüyü değiştirmesini önleyecektir.

Anizotropik filtreleme kullandığınızda, kenarlığın genişliğini artırmanız gerekebileceğini unutmayın. Bunun nedeni, anizotropik filtrelemenin, örnek mahallenin boyutunu aşırı açılarda artıracağıdır.


Her dokunun kenarı etrafında bir kenarlık kullanarak ne demek istediğimi göstermek için, OpenGL'de bulunan çeşitli sarma modlarını göz önünde bulundurun. Özellikle dikkat edin CLAMP TO EDGE.

  http://lucera-project.com/blog/wp-content/uploads/2010/06/wrap.png

"Kenara Kadar Kelepçe" adı verilen bir mod olmasına rağmen, aslında ilgilendiğimiz şey bu değildir. Bu mod, normalize edilmiş doku koordinatlarının dışında kalan doku koordinatları için tek bir rengi doku çevresinde kenarlık olarak tanımlamanızı sağlar [0.0 -1.0] aralık.

İstediğimiz, CLAMP_TO_EDGE(alt-) doku için uygun aralığın dışındaki herhangi bir doku koordinatının, sınırların dışına çıktığı yönde son texel merkezinin değerini aldığı davranışı çoğaltmaktır . atlas sistemindeki doku koordinatları, (etkili) doku koordinatlarının dokunuzun dışındaki bir konuma işaret edebileceği tek senaryo, doku filtrelemenin ağırlıklı ortalama adımındadır.

Biz biliyoruz ki GL_LINEAR bu yüzden sadece 1 texel sınırını ihtiyaç yukarıdaki şekilde görüldüğü gibi 4 yakın komşuları örnek olacak. Anizotropik filtreleme kullanıyorsanız, daha geniş bir texel kenarlığına ihtiyacınız olabilir, çünkü belirli koşullar altında örnek mahalle boyutunu artırır.

Sınırı daha açık bir şekilde gösteren bir doku örneği, ancak amaçlarınız için sınır 1 texel veya 2 texels geniş yapabilirsiniz.

  

(NOT: Bahsettiğim kenarlık görüntünün dört kenarının etrafındaki siyah değil, dama tahtası deseninin düzenli olarak tekrarlanmasını bıraktığı alan)

Merak ediyorsanız, işte bu yüzden anizotropik filtreleme yapmaya devam ediyorum. Örnek mahallenin şeklini açıya göre değiştirir ve filtreleme için 4'ten fazla tekstilin kullanılmasına neden olabilir:

  http://www.arcsynthesis.org/gltut/Texturing/ParallelogramDiag.svg

Kullandığınız anizotropi derecesi ne kadar büyük olursa, 4'ten fazla metin içeren örnek mahallelerle uğraşmanız daha olasıdır. Anizotropik filtreleme durumlarının çoğu için 2 texel kenarlık yeterli olmalıdır.


Son olarak GL_CLAMP_TO_EDGE, bir GL_LINEARdoku filtresinin varlığında davranışı çoğaltan paketlenmiş bir doku atlası nasıl inşa edilir :

( Siyah koordinatlarda X ve Y'den 1 çıkarın, yayınlamadan önce resmi okuduğumu kanıtlamadım. )   

Sınır depolama nedeniyle, bu atlasta 4 256x256 doku depolamak, 516x516 boyutlarında bir doku gerektirir. Atlas oluşturma sırasında kenarlıkları texel verileriyle nasıl dolduracağınıza bağlı olarak renk kodludur:

  • Kırmızı = Doğrudan altındaki texel ile değiştir
  • Sarı = Doğrudan yukarıdaki texel ile değiştir
  • Yeşil = Doğrudan soldaki texel ile değiştir
  • Mavi = Doğrudan sağdaki texel ile değiştirin

Bu paketlenmiş örnekte etkili bir şekilde, atlastaki her doku atlasın 258x258 bölgesini kullanır, ancak görünür 256x256 bölgesine eşlenen doku koordinatları oluşturacaksınız. Sınırlayıcı dokular sadece doku filtrelemesi atlastaki dokuların kenarlarında yapıldığında ve tasarım şeklini taklit ettiğinde kullanılır GL_CLAMP_TO_EDGE.

Merak ediyorsanız, benzer bir yaklaşım kullanarak diğer sarma modlarını GL_REPEATuygulayabilirsiniz - doku atlasındaki sol / sağ ve üst / alt kenarlık metinlerini ve bir parça akıllı doku koordinat matematiğini gölgelendirici. Bu biraz daha karmaşık, bu yüzden şimdilik bunun için endişelenme. Sadece sprite sayfaları ile uğraştığınız için kendinizi sınırlayın GL_CLAMP_TO_EDGE:)


Teşekkürler @AndonMColeman, yine de bunun nasıl çalıştığını anladığımdan emin olmadığım için bir diyagramda kenarlığı gösterebilir misiniz - yine, doku nesneme uygulandığında kenarlığı içereceği anlamına gelir mi? Gerçek dokunun
dörtlüğemin

@ user22241 Kesinlikle, bu kenarlığın çalışma şekli dokuyu kenarındaki dokuyu çoğaltmaktır.
Andon M. Coleman

@ user22241: Hayır, bu kenarlık normal koşullar altında görünmez. Paketli dokularınıza doku koordinat hesaplaması için aynı boyutlara sahip olarak davranacaksınız, kenarlığı atlamak için bunlara bir ofset uygulayacaksınız. Kenarlığın tüm amacı, doğrusal doku örneklemesinin hareketli sayfanızdaki ayrı görüntülere ait olan dokulara aşırı ulaşmasını ve örneklemesini önlemektir. En yakın komşu örneklemini kullanırsanız, bunların hiçbiri gerekli değildir, ancak daha sonra kötü taklit spritelar alırsınız.
Andon M. Coleman

Zekice ayrıntılı cevap - teşekkürler! Eğer yapabilirsem son bir şey. Doku koordinatlarıma eklemek için 'ofseti' nasıl çalıştırabilirim? Ben sadece 1 / widthOfTexture olacağını söylemek doğru muyum?
BungleBonce

@ user22241: Evet, doku görüntüsünün başlangıcı X yönünde + 1 / widthOfTexture ve Y yönünde + 1 / heightOfTexture olur. Her bir doku etrafında bir kenarlık olacak. 3. yatay doku için doku koordinatlarını hesaplamak istediğinizde, bu doku için paketlenmiş konum aslında +5 texels (ilk doku kenarlığı için +2 texels, ikinci doku kenarlığı için +2 ve başlangıç ​​için +1 diğer 2 dokunun genişliğine ek olarak. Sadece yazmak karmaşık görünüyor; Gerekirse size bir diyagram çizebilirim :)
Andon M. Coleman
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.