Özel Filtrelere (CSS Gölgelendiriciler olarak da bilinir) giriş

Paul Lewis

Özel Filtreler veya daha önce çağrıldıkları haliyle CSS Gölgelendiricileri, DOM içeriğinizde WebGL'nin gölgelendiricilerinin gücünden yararlanmanıza olanak tanır. Şu anki uygulamada kullanılan gölgelendiriciler WebGL'dekilerle neredeyse aynı olduğundan, bir adım geri çekilmeniz ve bazı 3D terminolojisini ve biraz da grafik ardışık düzenini anlamanız gerekir.

Kısa bir süre önce LondonJS'ye teslim ettiğim bir sunumun kaydedilmiş sürümünü buraya ekledim. Bu videoda, anlamanız gereken 3D terminolojiye, karşılaşacağınız farklı değişken türlerine ve Özel Filtreleri hemen kullanmaya nasıl başlayabileceğinize ilişkin genel bir bakış sunuyorum. Ayrıca, demoları kendiniz oynayabilmek için slaytları almalısınız.

Gölgelendiricilere Giriş

Daha önce, gölgelendiricilerin ne olduğuna ve WebGL açısından bunları nasıl kullanabileceğinize dair iyi bir döküm için gölgelendiricilere giriş yazmıştım. Özel Filtreler kavramlarının ve dilinin çoğu mevcut WebGL gölgelendirici terminolojisine dayandığından, gölgelendiricilerle daha önce hiç çalışmadıysanız, bu konuyu daha ileri bir aşamaya geçmeden önce okumanız gerekir.

Bununla birlikte, Özel Filtreleri etkinleştirelim ve işleme devam edelim!

Özel Filtreleri Etkinleştirme

Özel Filtreler, hem Chrome hem de Canary'nin yanı sıra Android için Chrome'da kullanılabilir. about:flags uygulamasına gidip "CSS Gölgelendiricileri"ni arayıp etkinleştirin ve tarayıcıyı yeniden başlatın. Artık hazırsınız!

Söz dizimi

Özel Filtreler, DOM öğelerinize zaten uygulayabileceğiniz blur veya sepia gibi filtre grubunu genişletir. Eric Bidelman, bunlar için mutlaka göz atmanız gereken harika bir oyun alanı aracı yazdı.

Bir DOM öğesine Özel Filtre uygulamak için aşağıdaki söz dizimini kullanırsınız:

.customShader {
    -webkit-filter:

    custom(
        url(vertexshader.vert)
        mix(url(fragment.frag) normal source-atop),

    /* Row, columns - the vertices are made automatically */
    4 5,

    /* We set uniforms; we can't set attributes */
    time 0)
}

Buradan, tepe noktası ve parça gölgelendiricilerimizi, DOM öğemizin bölünmesini istediğimiz satır ve sütun sayısını ve geçirmek istediğimiz üniformaları bildirdiğimizi göreceksiniz.

Burada dikkat edilmesi gereken son bir nokta da, parça gölgelendiricinin etrafında mix() işlevini bir karışım modu (normal) ve bir birleşik mod (source-atop) ile kullandığımızdır. Neden bir mix() işlevine ihtiyaç duyduğumuzu görmek için parça gölgelendiricinin kendisine göz atalım.

Piksel İtme

WebGL'nin gölgelendiricilerini biliyorsanız Özel Filtreler'de her şeyin biraz farklı olduğunu göreceksiniz. Örneğin, parça gölgelendiricimizin pikselleri doldurmak için kullandığı dokuları oluşturmuyoruz. Bunun yerine, filtrenin uygulandığı DOM içeriği otomatik olarak bir dokuyla eşlenir ve bunun iki anlamı vardır:

  1. Güvenlik nedeniyle DOM dokusunun piksel rengi değerlerini tek tek sorgulayamıyoruz.
  2. Son piksel rengini (en azından mevcut uygulamalarda) kendimiz ayarlamıyoruz, yani gl_FragColor değerine izin verilmiyor. Bunun yerine, DOM içeriğini oluşturmak isteyeceğiniz varsayılır ve yapmanız gereken, css_ColorMatrix ve css_MixColor aracılığıyla piksellerini dolaylı olarak değiştirmektir.

Bu, parça gölgelendiricilerden oluşan Hello World'ün daha çok aşağıdaki gibi görüneceği anlamına gelir:

void main() {
    css_ColorMatrix = mat4(1.0, 0.0, 0.0, 0.0,
                            0.0, 1.0, 0.0, 0.0,
                            0.0, 0.0, 1.0, 0.0,
                            0.0, 0.0, 0.0, 1.0);

    css_MixColor = vec4(0.0, 0.0, 0.0, 0.0);

    // umm, where did gl_FragColor go?
}

DOM içeriğinin her bir pikseli css_ColorMatrix ile çarpılır. Bu durumda yukarıdaki örnekte, kimlik matrisi olarak hiçbir şey yapılmaz ve RGBA değerlerinin hiçbirini değiştirmez. Diyelim ki kırmızı değerleri koruyacak olsaydık şunun gibi bir css_ColorMatrix kullanacağız:

// keep only red and alpha
css_ColorMatrix = mat4(1.0, 0.0, 0.0, 0.0,
                        0.0, 0.0, 0.0, 0.0,
                        0.0, 0.0, 0.0, 0.0,
                        0.0, 0.0, 0.0, 1.0);

4D (RGBA) piksel değerlerini matrisle çarptığınızda, diğer taraftan değiştirilmiş bir piksel değeri (bu örnekte de yeşil ve mavi bileşenleri sıfırlayan bir değer) elde ettiğinizi görebilirsiniz.

css_MixColor, temel olarak DOM içeriğinizle birlikte kullanmak istediğiniz bir temel renk olarak kullanılır. Karıştırma işlemi, sanat paketlerinden aşina olduğunuz harmanlama modlarıyla (yer paylaşımı, ekran, renk soldurma, sert ışık vb.) gerçekleştirilir.

Bu iki değişkenin pikselleri değiştirmesinin birçok yolu vardır. Karışım ve birleşik modların nasıl etkileşimde bulunduğunu daha iyi anlamak için Filtre Efektleri spesifikasyonuna göz atmalısınız.

Köşe Oluşturma

WebGL'de ağımızın 3D noktalarının oluşturulmasında tüm sorumluluğu biz üstleniyoruz, ancak Özel Filtreler'de tek yapmanız gereken istediğiniz satır ve sütun sayısını belirlemektir. Tarayıcı, DOM içeriğinizi otomatik olarak birkaç üçgene ayırır:

Köşe oluşturma
Satırlara ve sütunlara bölünmüş bir resim

Daha sonra, bu köşelerin her biri, işleme amacıyla köşe gölgelendiricimize geçirilir ve bu, ihtiyaç duyduğumuzda bunları 3D uzayda hareket ettirmeye başlayabileceğimiz anlamına gelir. Kısa sürede muhteşem efektler elde edebilirsiniz.

Akordeon efekti
Akordeon efektiyle bozulan bir resim

Gölgelendiricilerle Animasyon Oluşturma

Gölgelendiricilerinize animasyonlar eklemek onları eğlenceli ve ilgi çekici hale getirir. Bunu yapmak için, tek tip değerleri güncellemek üzere CSS'nizde bir geçiş (veya animasyon) kullanmanız yeterlidir:

.shader {
    /* transition on the filter property */
    -webkit-transition: -webkit-filter 2500ms ease-out;

    -webkit-filter: custom(
    url(vshader.vert)
    mix(url(fshader.frag) normal source-atop),
    1 1,
    time 0);
}

    .shader:hover {
    -webkit-filter: custom(
    url(vshader.vert)
    mix(url(fshader.frag) normal source-atop),
    1 1,
    time 1);
}

Yukarıdaki kodda dikkat edilmesi gereken nokta, geçiş sürecinde zamanın 0 - 1 arasının azalacağıdır. Gölgelendiricinin içinde time ifadesini belirtebilir ve geçerli değerini kullanabiliriz:

    uniform float time;

uniform mat4 u_projectionMatrix;
attribute vec4 a_position;

void main() {
    // copy a_position to position - attributes are read only!
    vec4 position = a_position;

    // use our time uniform from the CSS declaration
    position.x += time;

    gl_Position = u_projectionMatrix * position;
}

Oyun oynamaya başlayın!

Özel Filtreler ile oynamak çok eğlencelidir ve onlar olmadan oluşturabileceğiniz harika efektler zor (ve bazı durumlarda imkansız) olur. İşler daha yeni ve işler epey değişiyor. Ama projelerine biraz gösteri dünyası ekleyeceksiniz. O halde denemeye ne dersiniz?

Ek Kaynaklar