Kayıt: Feb 14, 2003 Mesajlar: 94 Nereden: İstanbul
Tarih: Fri Jul 01, 2005 4:45 pm Mesaj konusu: OpenGL de alpha testing problemleri ve transparency
Selamlar.
Uzun zamandır aşmaya çalıştığım,ama her seferinde başarısızlığa uğradığım iğrenç bir sorunum var.Uğraştığım işimi bitirmemi engellediği için tane tane,detaylı detaylı ne olduğunu anlatmaya çalışayım:
1-Büyük bir terrain üstüne bir takım ağaçlar,askerler vb. yerleştiriyorum.Arazi üzerinde tamamen hareketli ve her yana dönebilen bir kamera var.Bu nedenle kameranın görüş alanı içinde rahatlıkla aynı anda onlarca ağaç veya asker bulunabileceği için,bu birimler basit .bmp dosyalarından oluşuyor.Bir bmp resminin içinde mesela bir askerin yürüme,koşma,durma,ölme gibi hareketleri var. Bunları sırayla ekrana çizdirip basit animasyonlar oluşturacağım.Şimdi sorunumu daha basit bir şekilde dile getirebilmem için örnek olarak bir ağaç resmini ele alayım,zira onda animasyon falan yok.
Resimde gördüğünüz kahverengi bölgeyi,ağaç texture 'ünü render ettirirken görünmez kılmak istiyorum.Kısaca bu renge sahip pixeller için transparanlık istiyorum.Şimdi benim bilgim dahilimde OpenGL'de bu işlemi gerçekleştirebilmek için iki seçenek var:
1-Blending
2-Alpha Testing
Önceleri blending kullanmayı düşünüyordum,ancak bu yöntemin yapısı gereği,sahneyi her çizdirdiğimde ne kadar cisim,asker veya benzeri birim varsa bunları back to front sorting yapmak gerekiyor ki,bu fps için oldukça vahim bir durum arzediyor.Sorting olmadan da z buffer ile ilgili çok baş ağrıtıcı sorunlar meydana çıkıyor.(Zaten bir arkadaş benzeri bir durumdan şikayetçi yine forumda.)Bu nedenle blending seçeneğinden vazgeçtim.
2-Alpha testing gözüme daha mantıklı bir seçenek olarak göründü,hem sorting belasından kurtulmuş oluyordum,hem de blending den farklı olarak alphası 0 olan kahverengi bölgeler testi geçemediği için elenip raster işlemlerine girmiyordu.Yani hız açısından büyük avantaj sağlayacaktı.Bu nedenle alpa testing de karar kıldım.
OpenGL de texture yapmak için resimleri açtığımda,yukarıdaki gibi,kahverengi bölgenin rgb değerini taşıyan her pixelin alphasını 0'a eşit kıldım.Diğer yerlerin(asıl ağaç resminin) alphalarını 255 yaptım.Daha sonra
Kod:
glAlphaFunc(GL_GREATER,0.0f);
dedim.
Şimdi teorik olarak bu aşamadan sonra,ağaç resminin kahverengi bölgesinden ayrılmış olarak çizilmesi gerekiyordu,ama şöyle bir görüntü aldım:
Kahverengi bölge yok ama,ağaç etrafında kahverengi artıklar kalmış.Bunun neden meydana gelmiş olabileceği ile ilgili uzun süre kafa patlattım,google'da konu ile ilgili detaylı araştırmalar yaptım ama ne yazık ki sorunum ile ilgili tatmin edici bir sonuca ulaşamadım.Ancak bu durumla ile ilgili benim şöyle bir varsayımım var:Ben texture oluştururken Linear filtering kullanıyorum.Bu yöntemde ekrandaki pixele textureden sampling işlemleri yapılırken,eğer texture'ün orjinal boyutları ekrandakine uymuyorsa(ki %99.9 durum budur haliyle),pixele en yakın olan texellerin rgba değerlerinin ortalaması alınıp kaydediliyor.Yani normalde alpha değeri 0 olan kahverengi bir pixel,eğer asıl ağaç resmi ile kahverengi bölgenin tam sınırında yer alıyorsa,alpha değeri ağaç pixellerinden gelen 1 ile kahverengi pixellerden gelen 0ların ortalaması,yani (0.küsürat) gibi birşey oluyor.Bu nedenle aslında çizilmemesi gereken kahverengi pixeller alpha testi geçiyor ve çiziliyor.
3-Buna çözüm olarak bu tür pixellerin asla alamayacağı çok yüksek alpha değerleri ile tekrar denedim.
Mesela:
Kod:
glAlphaFunc(GL_GREATER,0.99);
veya
Kod:
glAlphaFunc(GL_EQUAL,1.0);
Bu durumda ise daha farklı bir sorun oluyor,asıl ağaç resminin kenarlarındaki pixellerin alpha değerleri filtering sonunda yine kahverengi pixellerin 0'ları ile birlikte ortalama bir alpha değeri aldığı için,1'den düşük geliyor.Bu nedenle bu sefer de asıl resmin pixelleri testi geçmeleri gerekirken geçemiyorlar.Texture'ün kenarları budanmış olarak gözüküyor.Bu durum ağaçlarda çok belli değil ama,askerlerin küçücük resimlerinde,kafalar,kollar falan neredeyse tamamiyle yok oluyor:
Bu ikisinin ortasını bulmaya çok uğraştım ama oluşan tüm görüntüler şu veya bu şekilde sorunlu.Sonuçta ne yapacağımı şaşırmış şekilde kala kaldım.Ne yapmam gerekir,bu transparanlık sorununu nasıl aşabilirim?Konuyla ilgili her türlü çözüm önerisine açığım.
Bende aynı sekilde kullanıyorum format olarakta TGA kullanıyorum hatta , herhnagi bi programla resimi boyarken ,R G B kanallarından sonra alpha kanalı için görülecek kısmı beyaz gorunmeyecek kısımı siyaha boyuyorum ve kodda glAlphaFunc fonksiyonunu assagidaki gibi kullanıorum ve gayet güzel calısıyor ama tabi bazen dedigin olay oluyor ama göz ardı edilicek sekilde. Kolay gelsin.
Kayıt: Jan 24, 2003 Mesajlar: 1134 Nereden: Bakırköyden.Yeni taşındık da...
Tarih: Fri Jul 01, 2005 6:25 pm Mesaj konusu:
ben interlaced png kullanıyorum masking e gerek kalmıyor ve hiçbir problem de olmuyor.arka plana rgb bir değer atacağına direk pshop tarzı bi programdan transparan yap daha iyi.
Kayıt: Feb 26, 2003 Mesajlar: 1258 Nereden: Dünya.Türkiye(54)
Tarih: Fri Jul 01, 2005 6:31 pm Mesaj konusu:
En iyi çözüm: Resmi belleğe aldıktan sonra, Anahtar renge göre, alpha kanalını oluşturduktan sonra, kırmızı rengi siyah yap ve Dokuyu öyle GL'e gönder... Böylece görüntü daha iyi olacaktır...
Kayıt: Feb 14, 2003 Mesajlar: 94 Nereden: İstanbul
Tarih: Fri Jul 01, 2005 8:11 pm Mesaj konusu:
Alıntı:
ben interlaced png kullanıyorum masking e gerek kalmıyor ve hiçbir problem de olmuyor.arka plana rgb bir değer atacağına direk pshop tarzı bi programdan transparan yap daha iyi.
Nomax bununla ilgili biraz daha bilgi verebilir misin?Söylediğinden anladığım kadarıyla bu formatın alpha kanalını dışarıdan photoshoptan elinle 0 yapınca transparanlık OpenGL'de herhangi bir işleme gerek kalmadan kendiliğinden oluşuyor.Fakat bildiğim kadarıyla blending veya alpha test her durumda gerekli idi.
Kayıt: Feb 26, 2003 Mesajlar: 1258 Nereden: Dünya.Türkiye(54)
Tarih: Fri Jul 01, 2005 9:01 pm Mesaj konusu:
TGA'nında BMP'nin de alpha kanalı vardır ve opsiyoneldir... Normal RGB 24Bit, RGBA yani Alpha kanalı ile 32Bittir... Bunu Photoshop yada benzeri kaliteli bir program ile belirleyebilirsin... OpenGL uygulamanda alpha kanalı ile uğraşmak zorunda kalmazsın... Doku oluşumu sırasında, GL_RGBA ile gl'e verebilirsin... Ama iki sisteminde avantajı kendine göre var, Key Color Alpha ve Alpha Channel, ikisinide sistemine oturttunmu rahat edersin...
Kayıt: Feb 14, 2003 Mesajlar: 94 Nereden: İstanbul
Tarih: Fri Jul 01, 2005 9:15 pm Mesaj konusu:
Tamam ben de biliyorum alpha channelin ne olduğunu ama benim sorunum bunun kullanımıyla ilgili.Transparan olmasını istediğin bir renk belirliyorsun,bu rengin olduğu pixellerde RGBA'nın A değeri 0 oluyor.Bu da tamam.
Ama sorun şu ki,OpenGL'in ekrana texture'ü çizerken doğrudan alpha değeri 0 olan pixelleri görünmez kılma gibi bir özelliği yok.(En azından benim bildiğim ve deneyip gördüğüm kadarıyla.Eğer böyle özellik var da ben bilmiyorsam ne ala,başım dertten kurtulur.)Yani sen ister photoshopla hazır 32 bitlik resim hazırlayıp alpha channelini 0 yap,ister 24 bitlik resmi kendin kodla açıp ona sonradan bir alpha channel ekleyip key colorda alphayı 0 yap,ne yaparsan yap,transparanlık efektine ulaşabilmen ya blending ya da alpha test yapmak zorundasın.Yani alpha channeli 0 yapmakla iş bitmiyor demek istediğim o.Nomax ise mesajında interlaced png formatında masking(yani blending) yapmaya gerek kalmadan sorunsuz transparanlık yaptığını söylüyor.Benim çelişkim burada.
Hocam sana bi site vericem bu sitenin en assagisindaki demo yu indir bi koduna bakın gayet basit ve güzel anlatılmıs, ben zamanında burdan calısmıstım ve gayet yardım etti bana. Kolay gelsin
LorenSoth çok teşekkür ederim arkadaşım, ama o sitedeki örnek zaten bende var
Hmm hadi ya
Dediğin olayı bir sitedede gormustum yabancı bi forumda biri benzer seyi sormustu ama onunki biraz daha farklıydı senin ilk sorununun aynısı ve senin gibide cozmustu yani o etrafındaki kahverengi pixel leri gecirmeyi basarmıstı ama deformasyon göz ardı edilebilir durumdaydıki herhalde hic muhabbeti olmamıstı neyse o forumu bulursam linkini koyucam.
Cuisinart cok yerinde gozlemler ve deneyler yapmissin. Senin de farkettigin gibi kahverengi kalintilarin sebebi lineer filtreleme. Anladigim kadariyla benim onerecegim cozum su;
2- de yazdigin metoddaki gibi glAlphaFunc(GL_GREATER,0.0f); kullan, lineer filtrelemeye devam et. Deseni opengl'e atarken soyle bi process zaten yapiyomussun;
Alıntı:
OpenGL de texture yapmak için resimleri açtığımda,yukarıdaki gibi,kahverengi bölgenin rgb değerini taşıyan her pixelin alphasını 0'a eşit kıldım.Diğer yerlerin(asıl ağaç resminin) alphalarını 255 yaptım
Simdi bunu yaparken A kanali olusturutosun ama RGB'ye dokunmuyosun. Benim onerim RGB uzerine de basit bi morfolojik filtre at(korkma cok basit bi islem ). http://www.cee.hw.ac.uk/hipr/html/dilate.html
Aynen burdaki islemi yapmiycaksin tabii ama demek istedigimi anlamissindir. Bu filtreyi desenin yesil kisimlarinin kahverengi ile bulustugu noktalarda is yapacak sekilde uyguluycaksin (hint: 8 connectivity). Sonuc olarak yesiller sanki genislemis gibi bi his vericek. Bu da kahverengi bozuklugu kaldiricak.
Kayıt: Feb 14, 2003 Mesajlar: 94 Nereden: İstanbul
Tarih: Sat Jul 02, 2005 5:17 am Mesaj konusu:
Alıntı:
2- de yazdigin metoddaki gibi glAlphaFunc(GL_GREATER,0.0f); kullan, lineer filtrelemeye devam et. Deseni opengl'e atarken soyle bi process zaten yapiyomussun;
Alıntı:
OpenGL de texture yapmak için resimleri açtığımda,yukarıdaki gibi,kahverengi bölgenin rgb değerini taşıyan her pixelin alphasını 0'a eşit kıldım.Diğer yerlerin(asıl ağaç resminin) alphalarını 255 yaptım
Simdi bunu yaparken A kanali olusturutosun ama RGB'ye dokunmuyosun. Benim onerim RGB uzerine de basit bi morfolojik filtre at(korkma cok basit bi islem ). http://www.cee.hw.ac.uk/hipr/html/dilate.html
Aynen burdaki islemi yapmiycaksin tabii ama demek istedigimi anlamissindir. Bu filtreyi desenin yesil kisimlarinin kahverengi ile bulustugu noktalarda is yapacak sekilde uyguluycaksin (hint: 8 connectivity). Sonuc olarak yesiller sanki genislemis gibi bi his vericek. Bu da kahverengi bozuklugu kaldiricak.
Mantıklı bir çözüm gibi duruyor,çok teşekkür ederim en kısa zamanda deneyeceğim.
Bu forumda yeni konular açamazsınız Bu forumdaki mesajlara cevap veremezsiniz Bu forumdaki mesajlarınızı değiştiremezsiniz Bu forumdaki mesajlarınızı silemezsiniz Bu forumdaki anketlerde oy kullanamazsınız