Framebuffer
Çevirmen Notu: “Framebuffer” sözcüğü tek kelimeden oluşmaktadır ve “çerçeve tamponu” olarak çevirisi uygun bulunmamaktadır. Framebuffer, RAM’in bir parçasıdır. Kendisi bir tampon değil, aslında tamponların birleşimine verilen isimdir. Türkçe karşılığı olmamakla birlikte, eğitsellerin çevirisi dahilinde “framebuffer” sözcüğü orijinal biçimi ile bırakılmıştır.
Şimdiye kadar birkaç çeşit ekran tamponu kullandık: Renk değerleri yazmak için bir renk tamponu (ing. collor buffer), derinlik bilgileri yazmak için bir derinlik tamponu(ing. depth buffer) ve nihayet bazı koşullara dayanarak belirli parçaları atmamıza izin veren bir şablon tamponu (ing. stencil buffer). Bu tamponların birleşimine framebuffer denir ve bellekte bir yere depolanır. OpenGL bize kendi framebuffer’ımızı tanımlama ve böylece kendi rengimizi, isteğe bağlı olarak bir derinlik ve şablon tamponu tanımlama esnekliği sağlar.
Şimdiye kadar yaptığımız sahneleme işlemlerinin tümü, varsayılan framebuffer’a bağlı olan sahneleme tamponlarının (ing. render buffers) üzerinde yapıldı. Varsayılan framebuffer pencere oluşturulduğunda yaratılır ve yapılandırılır (GLFW bunu bizim için yapmaktadır). Kendimiz framebuffer oluşturarak, sahnelemek için ek bir yol bulabiliriz.
Framebuffer uygulamaları hemen bir anlam ifade etmeyebilir,ancak sahnenizi farklı bir framebuffer’a yansıtmak, bir sahnede aynalar oluşturmamızı ya da örneğin etkili son-işlem (ing. post-processing) efektleri yapmamızı sağlar.İlk önce gerçekte nasıl çalıştıklarını tartışacağız ve sonra bu harika son-işlem efektlerini uygulayarak kullanacağız.
Framebuffer Oluşturma
OpenGL’deki diğer nesneler gibi, glGenFramebuffers
adlı bir işlevi kullanarak bir framebuffer nesnesi (kısaca FBO) oluşturabiliriz:
Bu nesne yaratma ve kullanma kalıbı, şimdiye kadar onlarca kez gördüğümüz bir şeydir. Bu yüzden kullanım işlevleri, gördüğümüz diğer tüm nesnelere benzer; ilk önce bir framebuffer nesnesi yaratır, onu aktif framebuffer olarak bağlar, bazı işlemleri yapar ve framebuffer’ı serbest bırakırız. Bağlama işlemi için glBindFramebuffer fonksiyonu kullanılır:
Framebuffer nesnesi, GL_FRAMEBUFFER hedefi ile bağlandığında, işlemler o andaki bağlı framebuffer’ı etkileyecektir. Ayrıca, bir framebuffer’ı GL_READ_FRAMEBUFFER veya GL_DRAW_FRAMEBUFFER ile sırasıyla okuma veya yazma hedeflerine bağlamak da mümkündür. GL_READ_FRAMEBUFFER öğesine bağlanan framebuffer, glReadPixels gibi tüm okuma işlemleri için kullanılırken, GL_DRAW_FRAMEBUFFER’a bağlanan framebuffer sahenleme, temizleme ve diğer yazma işlemlerinde hedef olarak kullanılır. Çoğu zaman bu ayrımı yapmanıza gerek kalmayacak ve genellikle her ikisine de GL_FRAMEBUFFER ile bağlanacaksınız.
Ne yazık ki, framebuffer’ımızı henüz kullanamıyoruz çünkü tamamlanmadı. Bir framebuffer’ın tamamlanabilmesi için aşağıdaki gereksinimler gerçekleşmelidir:
En az bir tampon ile ilişkilendirmek zorundayız (renk, derinlik ya da şablon tamponu).
En az bir renk ilişkilendirilmiş olmalıdır.
Tüm ekler tamamlanmış olmalıdır (ayrılmış bellek).
Her tamponun aynı sayıda örneği olmalıdır.
Eğer örneklerin ne olduğunu bilmiyorsanız endişelenmeyin,çünkü bir sonraki eğitselde bunu öğreneceğiz.
Gereksinimlerden, framebuffer için bir tür bağlantı oluşturmamız ve bu bağlantıyı framebuffer ile ilişkilendirmemiz gerektiği açıktır. Tüm gereklilikleri tamamladıktan sonra glCheckFramebufferStatus’u GL_FRAMEBUFFER ile çağırarak framebuffer’ı başarıyla tamamlayıp tamamlamadığımızı kontrol edebiliriz. “GL_FRAMEBUFFER_COMPLETE” döndürülürse devam etmeye hazırız:
Sonraki tüm sahneleme işlemleri, şu anda bağlı olan framebuffer eklerine işlenecektir. Framebuffer, bizim varsayılan frameebuffer’ımız olmadığı için sahneleme komutlarının pencerenin görsel çıktısı üzerinde bir etkisi olmaz. Bu sebeple, farklı bir framebuffer sahnelenmesi ekran dışı sahneleme (ing. off-screen rendering) olarak adlandırılır. Tüm sahneleme işlemlerinin ana pencere üzerinde görsel bir etkisi olmasını sağlamak için, varsayılan framebuffer 0’a bağlanarak tekrar etkin hale getirilmelidir:
Tüm framebuffer işlemleriyle işimiz bittiğinde, framebuffer nesnesini silmeyi unutmayın:
Şimdi bütünlük kontrolü yapılmadan önce, framebuffer ile bir veya daha fazla bağ (ing. attachment) kurmamız gerekir. Bir bağ, framebuffer için tampon görevi görebilen, onu imge olarak düşünebilen bir hafıza alanıdır. Bir bağ oluştururken iki seçeneğimiz var: Dokular veya renderbuffer nesneler.
Doku Bağlantısı
Bir dokuyu framebuffer’a bağlarken, tüm sahneleme komutları dokuya normal bir renk/derinlik ya da şablon tamponu gibi uygulanacaktır. Doku kullanmanın avantajı, tüm sahneleme işlemlerinin sonucunun gölgelendiricilerimizde kolayca kullanabileceğimiz bir doku imgesi olarak saklanmasıdır.
Bir framebuffer için doku oluşturmak, normal bir doku oluşturmayla kabaca aynıdır:
Buradaki ana fark, boyutları ekran boyutuna eşit ayarlamamız(nu gerekli olmasa da) ve NULL değerini dokunun veri parametresi olarak iletmemizdir. Bu doku için, sadece bellekte yer ayırıyoruz ve aslında doldurmuyoruz. Dokuyu doldurmak, framebuffer’e gönderdiğimiz anda gerçekleşir. Ayrıca, çoğu durumda bunlara ihtiyaç duymayacağımızdan, paketleme (ing. wrapping) yöntemlerinin veya mipmaplerin hiçbirini umursamadığımızı da unutmayın.
Tüm ekranınızı daha küçük veya daha büyük br boyuta sahip bir dokuya dönüştürmek istiyorsanız, dokunuzdaki yeni boyutlarlaa glViewport'u tekrar çağırmanız gerekir (framebuffer'da oluşturmadan önce), aksi takdirde doku veya ekranın sadece küçük bir kısmı doku üzerine çizilir.
Şimdi bir doku oluşturduğumuza göre, yapmamız gereken son şey onu framebuffer’a bağlamak.
The glFrameBufferTexture2D has the following parameters:
target: hedeflediğimiz framebuffer tipi (çizme, okuma ya da her ikisi).
attachment: bağ tipi. Şu anda bir renk bağı ile bağlantı sağlıyoruz. Sonundaki 0’ın, daha fazla renk eki ekleyebileceğimizi ifade ettiğini unutmayın. Daha sonraki bir derste buna başlayacağız.
textarget: bağlamak istediğimiz dokunun tipi
texture: bağlantı sağlanacak doku
level: mipmap seviyesi. Bunu 0’da tutuyoruz.
Renk bağlantılarının yanı sıra, framebuffer nesnesine bir derinlik ve şablon dokusu de ekleyebiliriz. Derinlik eklemek için, bağlantı türünü GL_DEPTH_ATTACHMENT olarak belirtiyoruz.Doku formatının ve dahili biçim (ing. internalformat) türünün, derinlik tamponunun depolama formatını yansıtması için GL_DEPTH_COMPONENT olması gerektiğini unutmayın. Bir şablon tamponu eklemek için ikinci argüman olarak GL_STENCIL_ATTACHMENT kullanır ve doku formatlarını GL_STENCIL_INDEX olarak belirtirsiniz.
Tek bir doku olarak hem bir derinlik tamponu hem de bir şablon tamponu eklemek de mümkündür. Dokunun her 32-bitlik değeri daha sonra 24-bit derinlik bilgisi ve 8-bit şablon bilgisi için oluşur. Bir doku olarak derinlik ve şablon tamponu eklemek için GL_DEPTH_STENCIL_ATTACHMENT tipini kullanırız ve dokunun formatlarını derinlik ve şablon değerleri içerecek şekilde yapılandırırız. Altyapıya bir doku olarak bir derinlik ve şablon tamponu bağlama örneği aşağıda verilmiştir:
Renderbuffer Nesne Bağlantısı
Renderbuffer nesneler OpenGL’e dokulardan sonra olası bir framebuffer bağlantı türü olarak getirildi. Tıpkı bir doku imgesi gibi, bir renderbuffer nesnesi de gerçek bir arabellektir. Örneğin; bayt dizisi, tamsayılar, pikseller vb. Bir renderbuffer nesnesi, verilerini OpenGL’in yerel sahneleme biçiminde saklamasına rağmen ek bir avantaja sahiptir, bu da ekran dışı sahneleme framebuffer’ı için optimize edilmesini sağlar.
Renderbuffer nesneleri, tüm sahneleme verilerini, dokuya özgü biçimlerde herhangi bir dönüşüm yapmadan doğrudan arabelleğine depolar, böylece, onları yazılabilir bir depolama ortamı olarak daha hızlı hale getirir. Bununla birlikte, renderbuffer nesneleri genellikle salt-yazılırdır. Bu nedenle onlardan okuma yapılamaz (doku erişiminde olduğu gibi).Onları glReadPixels işlevi ile okumak mümkündür, ancak doğrudan bağlantının kendisinden değil.
Verileri zaten kendi biçiminde olduğundan, veri yazarken veya basitçe verilerini diğer tamponlara kopyalarken oldukça hızlıdırlar. Geçiş(ing. switching) arabellekleri gibi işlemler, renderbuffer nesneleri kullanırken bu nedenle oldukça hızlıdır. Her sahneleme yinelemesinin sonunda kullandığımız glfwSwapBuffers işlevi, renderbuffer nesneleri ile de uygulanabilir:Biz sadece bir renderbuffer imgeye yazıyoruz ve sonunda diğerine takas yapıyoruz. Renderbuffer nesneleri bu tür işlemler için mükemmeldir.
Renderbuffer nesnesi oluşturma, framebuffer koduna benzerdir:
Ve benzer şekilde tüm sonraki renderbuffer işlemleri, geçerli rbo’yu etkileyecek şekilde renderbuffer nesnesini bağlıyoruz
Renderbuffer nesneleri genellikle salt-yazılır olduklarından, derinlik ve şablon bağlantıları olarak kullanılırlar. Çünkü çoğu zaman derinlik ve şablon tamponlarından değerleri okumamıza gerek kalmaz, ancak yine de derinlik testi ve şablon testini önemsiyoruz. Test için derinlik ve şablon değerlerine ihtiyacımız var, ancak bu değerleri örneklememiz gerekmiyor. Bu tamponlardan örnekleme yapmadığımız zaman, renderbuffer nesnesi genellikle daha optimize olduğu için tercih edilmektedir.
Derinlik ve şablon renderbuffer nesnesi oluşturma, glRenderbufferStorage işlevinin çağrılması ile gerçekleştirilir:
Bir renderbuffer nesnesi oluşturma işlemi doku nesnelerininkine benzerdir. Aradaki fark, bu nesnenin, doku gibi genel amaçlı bir veri tamponu yerine, bir imge olarak kullanılmak üzere özel olarak tasarlanmasıdır. Burada, hem derinlik hem de şablon tamponunu sırasıyla 24 ve 8 bit ile tutan dahili biçim olarak GL_DEPTH24_STENCIL8’i seçtik.
Yapılması gereken son şey aslında renderbuffer nesnesini bağlamaktır:
Renderbuffer nesneleri, framebuffer projelerinizde bazı iyileştirmeler sağlayabilir, ancak ne zaman renderbuffer nesnei ve ne zaman doku olarak kullanılacağının bilinmesi önemlidir. Verileri belirli bir tampondan hiçbir zaman örneklemeniz gerekmiyorsa, o belirli tampon için bir renderbuffer nesnesini kullanmak akıllıca olandır. Bir gün veriyi renk veya derinlik değerleri gibi belirli bir tampondan örneklemeniz gerekirse, bunun yerine bir doku kullanmanız gerekir. Performans açısından olsa da, muazzam derecede etkisi olmaz.
Bir Dokuyu Sahneleme
Framebuffer’ın nasıl çalıştığını bildiğimize göre artık onları kullanmanın vakti geldi. Yarattığımız bir framebuffer nesnesine bağlı renkli bir dokuyu sahneleyeceğiz ve sonra tüm ekrana yayılan basit bir dörtlü (ing. quad) üzerinde bu dokuyu çizeceğiz. Görsel çıktı, çerçevesiz olarak aynıdır, ancak bu kez hepsi tek bir dörtlünün üstüne basılmıştır. Bu neden yararlıdır? Bir sonraki bölümde nedenini göreceğiz.
Yapılması gereken ilk şey, gerçek bir framebuffer nesnesi oluşturmak ve bağlamaktır, bu nispeten basittir:
Sonra,framebuffer’a renk bağlantısı olarak eklediğimiz doku imgesi oluştururuz. Dokunun boyutlarını pencerenin genişliğine ve yüksekliğine eşit olarak belirliyor ve verilerini ilklendirmemiş olarak tutuyoruz:
Ayrıca OpenGL’in derinlik testi yapabildiğinden emin olmak istiyoruz (ve eğer isterseniz şablon testi), bu nedenle framebuffer’a derinlik (ve şablon) bağlantısı eklemeyi de sağlamalıyız. Sadece renk tamponu örnekleyeceğimizden ve diğer tamponları örneklemediğimizden, bu amaç için bir renderbuffer nesnesi oluşturabiliriz. Belirli tampondan örnekleme yapmayacağınız zaman iyi bir seçim olduklarını unutmayın.
Bir renderbuffer nesnesi oluşturmak çok zor değil. Hatırlamamız gereken tek şey, onu derinlik ve şablon eki oluşturma nesnesi olarak oluşturmamızdır. Dahili formatını, amaçlarımız için yeterince hassas olan GL_DEPTH24_STENCIL8 olarak ayarladık.
Renderbuffer nesnesi için yeterli bellek ayırdıktan sonra, renderbuffer bağını serbest bırakabiliriz.
Sonra, framebuffer’ı tamamlayabilmemiz için son bir adım olarak renderbuffer nesnesini, framebuffer’ın derinlik ve şablon bağına bağlarız:
Son bir önlem olarak, framebuffer’ın gerçekten tamamlanıp tamamlanmadığını kontrol etmek istiyoruz ve değilse, bir hata mesajı yazdırıyoruz.
Sonra da yanlış framebuffer’ın sahnelenmediğinden emin olabilmek için bağın çözüldüğünden emin olun.
Madem ki framebuffer tamamlandı, framebuffer sahnelemek için yapmamız gereken şey, varsayılan framebuffer yerine framebuffer nesnelerine bağlamaktır. Sonraki tüm sahneleme komutları şu anda bağlı olan framebuffer’ı etkileyecektir. Tüm derinlik ve şablon işlemleri, eğer varsa, bağlı framebuffer derinlik ve şablon bağlantılarından da okunacaktır. Örneğin bir derinlik tamponunu unutacak olursanız, derinlik testi işlemleri artık çalışmayacaktır, çünkü şu anda bağlı framebuffer’da bir derinlik tamponu mevcut değildir.
Dolayısıyla sahneyi tek bir doku ile çizmek için aşağıdaki adımları izlememiz gerekir:
Sahneyi, etkin framebuffer olarak bağlı yeni framebuffer ile oluşturun.
Varsayılan framebuffer’a bağlanın
Tüm ekranı, yeni framebuffer’ın renk tamponunu kullanarak doku olarak kaplayan bir dörtlü çizin.
Derinlik testi eğitselindeki aynı sahneyi çizeceğiz, ancak bu sefer eski model konteyner dokusunu kullanarak.
Dörtlüyü çizmek için yeni bir basit gölgelendirici seti oluşturacağız. Herhangi bir süslü püslü matris dönüşümünü dahil etmeyeceğiz. Çünkü yalnızca köşe koordinatlarını normalize cihaz koordinatları olarak vereceğiz, böylece bunları doğrudan köşe gölgelendiricisinin çıktısı olarak belirleyebiliriz. Köşe gölgelendiricisi şöyle görünüyor:
Çok süslü bir şey yok. Yapmamız gereken tek şey dokudan bir örnek almak olduğu için parça gölgelendiricisi daha da basit olacaktır:
Ekran için bir VAO oluşturmak ve yapılandırmak size kalmıştır. Framebuffer işleminin bir sahneleme yinelemesi aşağıdaki yapıya sahiptir:
Dikkat edilmesi gereken birkaç şey var. Öncelikle, kullandığımız her framebuffer kendi arabellek kümesine sahip olduğundan, bu arabelleklerin her birini glClear işlevini çağırarak ayarlanan uygun bitlerle siliyoruz. İkincisi, dörtlü çizerken, derinlik testini devre dışı bırakıyoruz çünkü derinlik testini gerçekten umursamıyoruz çünkü basit bir dörtlü çiziyoruz; normal sahneyi çizerken yine derinlik testini etkinleştirmek zorunda kalacağız.
Burada yanlış gidebilecek bazı adımlar vardır, bu nedenle çıktınız yoksa, hata ayıklamayı (ing. debug) deneyin ve eğitselin ilgili bölümlerini yeniden okuyun. Her şey başarılı bir şekilde çalıştıysa, şuna benzeyen görsel bir sonuç alırsınız.
Solda, derinlik testi eğitiminde gördüğümüzle aynı olan görsel çıktı gösteriliyor, ancak bu kez basit bir dörtlü oluşturuldu. Sahneyi tel kafes içinde oluşturursak, görünür hale gelir, varsayılan çerçevede yalnızca bir dörtlü çizdik.
Burada uygulamanın kaynak kodunu bulabilirsiniz.
Tamamen sahnelenmiş piksellerinin her birine tek bir doku imgesi olarak serbestçe erişebildiğimiz için, parça gölgelendiricisinde bazı ilginç efektler oluşturabiliriz. Tüm bu ilginç etkilerin kombinasyonuna işleme-sonrası efekti denir.
İşleme sonrası (ing. Post-processing)
Artık tüm sahne tek bir dokuya dönüştürüldüğüne göre, sadece doku verilerini manipüle ederek bazı ilginç efektleri oluşturabiliriz. Bu bölümde size daha popüler olan işleme sonrası efektlerden bazılarını ve yaratıcılıklarla kendi efektlerinizi nasıl oluşturabileceğinizi göstereceğiz.
En basit işleme sonrası efektlerden biriyle başlayalım.
Tersine çevirme
Render çıktısının her bir rengine erişimimiz var, bu nedenle parça gölgelendiricide bu renkleri tersine çevirmek o kadar zor değil. Ekran dokusunun rengini alıyoruz ve bunu 1.0
'dan çıkararak tersine çeviriyoruz:
Ters çevirme nispeten basit bir işleme sonrası efekt olsa da, oldukça ilginç sonuçlar yaratır:
Artık tüm sahnedeki tüm renkler, parça gölgelendiricisindeki tek bir kod satırıyla ters çevrilmiştir. Oldukça havalı değil mi?
Gri tonlama
Bir başka ilginç efekt ise, beyaz, gri ve siyah renkler haricindeki tüm renkleri sahneden kaldırmaktır. Bunu yapmanın kolay bir yolu, tüm renk bileşenlerini alıp sonuçlarının ortalamasını almaktır:
Bu zaten oldukça iyi sonuçlar yaratıyor, ancak insan gözü yeşil renklere ve en az da maviye daha duyarlı olma eğilimindedir, bu nedenle fiziksel olarak en doğru sonuçları elde etmek için ağırlıklı kanalları kullanmamız gerekecek:
Muhtemelen farkı hemen algılayamayacaksınız, ancak daha karmaşık sahnelerde, bu tür ağırlıklı gri tonlama efekti daha gerçekçi olma eğilimindedir.
Kernel efektleri
Tek bir doku imgesinde işleme sonrası efekt yapmanın bir başka avantajı da, dokunun diğer bölümlerinden renk değerlerini gerçekten örnekleyebilmemizdir. Örneğin, mevcut doku koordinatı etrafında küçük bir alan alabilir ve mevcut doku değeri etrafında birden çok doku değerini örnekleyebiliriz. Daha sonra bunları yaratıcı şekillerde birleştirerek ilginç efektler yaratabiliriz.
Bir kernel (veya konvolüsyon matrisi), çevreleyen piksel değerlerini kernel değerleriyle çarpan ve tek bir değer oluşturmak için hepsini bir araya getiren, geçerli piksel üzerinde ortalanmış küçük bir matris benzeri değerler dizisidir. Dolayısıyla, temel olarak doku koordinatlarına mevcut pikselin çevresindeki yönlerde küçük bir ofset ekliyoruz ve sonuçları kernel'e göre birleştiriyoruz. Aşağıda bir kernel örneği verilmiştir:
Bu çekirdek, çevreleyen 8 piksel değerini alır ve bunları 2 ile ve mevcut pikseli -15 ile çarpar. Bu örnek çekirdek, temel olarak çevreleyen pikselleri çekirdekte belirlenen bir ağırlıkla çarpar ve mevcut pikseli büyük bir negatif ağırlıkla çarparak sonucu dengeler. Tüm ağırlıkları bir araya toplarsanız, internette bulacağınız çoğu çekirdeğin toplamı 1 olur. 1'e kadar toplamazlarsa bu, elde edilen doku renginin orijinal doku değerinden daha parlak veya daha koyu bittiği anlamına gelir.
Çekirdekler, kullanımları, denenmeleri oldukça kolay olduğundan ve çevrimiçi olarak birçok örnek bulunabildiğinden, sonradan işleme için son derece yararlı bir araçtır. Çekirdekleri gerçekten desteklemek için parça gölgelendiricisini biraz uyarlamamız gerekiyor. Kullanacağımız her bir çekirdeğin 3x3 çekirdek olduğunu varsayıyoruz (çoğu çekirdek budur):
Parça gölgelendiricide, ilk olarak her çevreleyen doku koordinatı için 9 vec2 ofsetinden oluşan bir dizi oluşturuyoruz. Ofset, beğeninize göre özelleştirebileceğiniz sabit bir değerdir. Daha sonra çekirdeği tanımlıyoruz, bu örnekte, her bir renk değerini çevreleyen tüm pikselleri ilginç bir şekilde örnekleyerek keskinleştiren keskinleştirilmiş bir çekirdek. Son olarak, örnekleme yaparken her bir ofseti mevcut doku koordinatına ekleriz ve ardından bu doku değerlerini, birlikte eklediğimiz ağırlıklı çekirdek değerleriyle çarpıyoruz.
Bu özel keskinleştirilmiş çekirdek şuna benzer:
Bu, oyuncunuzun narkotik macerada nerede olabileceğine dair bazı ilginç etkiler yaratabilir.
Bulanıklık
Bulanıklaştırma efekti oluşturan bir kernel şu şekilde tanımlanır:
Tüm değerlerin toplamı 16 olduğu için, basitçe birleştirilmiş örneklenmiş renkleri döndürmek son derece parlak bir renkle sonuçlanacaktır, bu nedenle her bir çekirdeğin değerini 16'ya bölmemiz gerekir. Sonuçta ortaya çıkan çekirdek dizisi şöyle olur:
Parça gölgelendiricisindeki çekirdek kayan diziyi değiştirerek, peşinde olduğumuz işlem sonrası efektini tamamen değiştiriyoruz. Şimdi şuna benzer:
Böyle bir bulanıklık efekti ilginç olasılıklar yaratır. Örneğin, sarhoş birinin etkisini yaratmak için bulanıklık miktarını zaman içinde değiştirebiliriz veya ana karakter gözlük takmadığında bulanıklığı artırabiliriz. Bulanıklaştırma ayrıca bize sonraki eğitimlerde kullanacağımız renk değerlerini düzeltmek için yararlı bir yardımcı program sunar.
Bir kez bu kadar küçük bir çekirdek uygulamasına sahip olduğumuzda, havalı işlem sonrası efektler yaratmanın oldukça kolay olduğunu görebilirsiniz. Size bu tartışmayı bitirmek için son bir popüler efekt gösterelim.
Kenar algılama
Aşağıda, keskinleştirilmiş kernel'e benzer bir kenar algılama çekirdeği bulabilirsiniz:
Bu çekirdek, tüm kenarları vurgular ve geri kalanını koyulaştırır. Bu, bir görüntünün yalnızca kenarlarını önemsediğimizde oldukça yararlıdır.
Bunun gibi çekirdeklerin Photoshop gibi araçlarda görüntü işleme araçları / filtreleri olarak kullanılması muhtemelen şaşırtıcı değildir. Bir grafik kartının son derece paralel yeteneklere sahip parçaları işleme becerisi nedeniyle, görüntüleri piksel başına göre gerçek zamanlı olarak göreceli kolaylıkla işleyebiliriz. Bu nedenle görüntü düzenleme araçları, görüntü işleme için grafik kartlarını daha sık kullanma eğilimindedir.
Çeviri: Nezihe Sözen
Orijinal Kaynak: Framebuffers
Last updated