Bu sayfadaki yazılar
Sayfanın metni
Sayfa 47
OpenGL ya da Direct3D ile çalışırken texture stage'ler arasında da (multi-texturing yaptığınızı düşünün) blending yapabilirsiniz. Texture'ları oluşturan texel'ler blending hesaplamalarına girerler ve oluşan texel değerleri diğer pipeline seviyelerine (esasında eğer varsa per fragment operations'a, yoksa frame buffer'a) yollanır. Frame buffer ile blending'de ise blending hesaplamaları frame buffer'da yazılı olan pixel değerleri (destination, dst) ile pipeline'dan gelen (rasterizasyon ve texture mapping sonucu oluşan pixel'ler) yeni pixel değerleri (source, src) arasında olur. Bu hesaplamalar OpenGL pipeline'ının en sonunda "per fragment operations" denen kısımda olur ve alpha blending olarak bilinir. Alpha blending işlemi frame buffer okumaları (destination pixel'lerin de hesaba katıldığını unutmayın) da içerdiğinden çok sık yapılması önerilmez. Bizim yöntemimizde viewport'taki tüm pixel'lerle alpha blending yapacağız. Performans bakımından günümüz kartları için pek fazla sorun yok esasında. Source ve destination pixel'ler anlaşıldıysa blending faktörlerinin nasıl seçildiğine bakalım:
OpenGL'de Alpha Blending yaparken önce Blending state'ini glEnable(GL_BLEND); ile aktif hale getiririz. Sonra glBlendFunc(srcfactor,dstfactor); ile de source ve destination pikseller için blending faktörlerini ayarlarız.
Not: glBlendFunc'a argüman olarak srcfactor ve dstfactor yazdım. Bunu sadece ilk argümanın source pikseller için, diğerinin de destination pikseller için olduğunu belirtmek için yaptım. Bu argümanlar GL_ONE, GL_SRC_COLOR vs. gibi OpenGL'de tanımlı sabitler olacak. Bu sabitlerin tam listesi için OpenGL referanslarına bakın.
İşin matematiğine geçmeden önce belirtmem gereken bir şey var. Burada bahsedeceğim blending yöntemi additive blending diye bilinen yöntemdir. OpenGL spesifikasyonu sadece bir blending yöntemi tanımlar. O da additive blending'dir. Additive blending dışındaki yöntemler: subtractive (reverse subtractive) ve min-max blending yöntemleridir. Direct3D'de de bu yöntemler tanımlıdır. Mesela aşağıdaki kod parçası kullanılacak blend operasyonunu subtractive olarak seçer.
device->SetRenderState(D3DRS_BLENDOP,D3DBLENDOP_SUBTRACT);
Direct3D için SDK'da D3DBLENDOP Enumerated Type isimli kısma bakarak daha fazla bilgi edinebilirsiniz. OpenGL'e geri dönersek, OpenGL'de additive blending dışındaki yöntemler extension mekanizmasıyla programcıların kullanımına sunulmuştur. Genel blending yöntemlerini şöyle özetleyelim:
Kullanacağım notasyon şöyle olacak:
Cf --> Blending operasyonları sonucu oluşan renk (final color value) Cs --> Source pixel'in rengi Cd --> destination pixel'in rengi S --> Source pixel'in blend faktörü D --> Destination pixel'in blend faktörü
Additive Blending:
Cf = Cs * S + Cd * D olur ve if ( Cf > 1.0 ) Cf = 1.0 else if(Cf <= 1.0) Cf = Cf
Yukarıdaki if - else bloğuyla işlemin saturated olduğunu anlatmak istedim. Yani oluşan renk değerleri 1.0'ın üzerine çıkamaz.
Subtractive Blending:
Klavyeyle gezinmek için ← ve → tuşları.
Sayfa 46
Bu yazıda basit geçiş (transition) efektlerinden biri olan "fade"den bahsedeceğim. Efekt birden fazla yöntemle yapılabilir. Detaya girmeden yazıda anlatılacak yöntemlere bir bakalım:
1) Frame Buffer ile Blending. (OpenGL ve fixed pipe ile) 2) Render to Texture (OpenGL ve fixed pipe ile) 3) Pixel Shader (Direct3D ve programlanabilir pipe ile)
Görüldüğü gibi herkes için bir şeyler var (sensei için bile hehe :) ). Tutorial popüler grafik API'ları ile tecrübesi olan (ileri seviye bilgi gerekmiyor) coder'lar düşünülerek hazırlandı. Yeri gelmişken söylemek istediğim bir şey var. Yazıda çok miktarda İngilizce kelime (çoğu teknik terim) olabilir. Grafik programlama terminolojisini bilenler için sorun olmaz sanırım ama Türkçeleştirme için ekstra efor sarf etmeyeceğim. Yani gidip de texture map için doku eşlemi falan demeyeceğim ama gereken yerlerde de terimler/kavramlar hakkında gerekli açıklamaları yapacağım.
Birisi Fade in mi dedi??
Ne anlattığımızı detaylıca açıklamanın vakti geldi. Farz edelim bir demo yapıyorsunuz. Sahneler (ya da part'lar mı diyelim..) arası geçişlerin de yumuşak olmasını istiyorsunuz.. Yani ani, kütük gibi geçişler olmayacak. Mesela ekranın yavaşça kararması ya da kararmış bir ekrandan sahnenin yavaş yavaş görünür hale gelmesi gibi şeylerden bahsediyorum. Sanırım yapmak istediğimiz şey anlaşılıyor. Şimdi gerekli tanımları yapalım:
Fade in: Gösterilmek istenen sahnenin yavaş yavaş görünür hale gelmesi. Genellikle siyah ekrandan başlanır ve sahne zamanla görünür hale gelir. Siyah renk zorunluluk değil tabii ki. İstediğiniz renkten başlayabilirsiniz.
Fade out: Sahnenin yavaş yavaş gözden kaybolması durumu. Genellikle siyah renge doğru gidip ekranı karartırız. Siyah dışındaki renklere de gitmek mümkün.
Tamam şimdi bu iki efekti nasıl yapabiliriz ona bakalım.
1) Frame Buffer ile Blending Yöntemi
Bu yöntem için yapılması gerekenleri kısaca bir sıralayalım, sonra detaylarına gireceğiz.
- Sahnenizi normalce çizdirin. - Depth Test'i kapatın.
- Orthographic projeksiyona geçin.
- Alpha Blending'i aktif hale getirin.
- Screen Aligned Quad (Tüm ekranı kaplayan dörtgen) çizdirin. - Alpha Blending'i kapatın.
- Tüm çizdirim işlemlerini bitirin.
Bu yöntem full-screen alpha blending kullanıyor. Önce sahneniz neyse onu çizdiriyorsunuz, ondan sonra orthographic projeksiyon moduna geçip tam ekran bir dörtgen çizdiriyorsunuz. Dörtgeni çizdirirken, dörtgeni oluşturan vertex'lerdeki alpha değerlerini zamanla 0'dan 1'e ya da 1'den 0'a doğru çekiyoruz.
Frame Buffer ile Blending ve Doğru Blending Faktörlerini Seçmek
Yöntemin ismine frame buffer ile blending dedim. Peki nedir frame buffer ile blending?