कस्टम फ़िल्टर यानी सीएसएस शेडर के बारे में जानकारी

कस्टम फ़िल्टर या CSS शेडर जैसा पहले कॉल किया जाता था, आपको अपनी DOM कॉन्टेंट के साथ WebGL के शेडर का इस्तेमाल करने की सुविधा देते हैं. चूंकि वर्तमान क्रियान्वय में शेडर का उपयोग आमतौर पर WebGL के समान ही होता है, इसलिए आपको थोड़ा पीछे जाकर कुछ 3D शब्दावली और ग्राफ़िक पाइपलाइन का थोड़ा-बहुत समझना होगा.

मैंने हाल ही में लंदन में डिलीवर की गई अपनी प्रज़ेंटेशन का रिकॉर्ड किया हुआ वर्शन शामिल किया है. इस वीडियो में, मैंने 3D शब्दावली के बारे में खास जानकारी दी है. आपको यह समझने की ज़रूरत है कि आपको किस तरह के वैरिएबल टाइप देखने को मिलेंगे. साथ ही, कस्टम फ़िल्टर का इस्तेमाल करके आज ही कस्टम फ़िल्टर का इस्तेमाल कैसे किया जा सकता है. डेमो के साथ खुद खेलने के लिए, स्लाइड को भी कंट्रोल करें.

शेडर के बारे में जानकारी

मैंने पहले भेजना के बारे में शुरुआती जानकारी दी है. इससे आपको इस बारे में बेहतर जानकारी मिलेगी कि शेडर क्या होते हैं और WebGL के हिसाब से, आप उनका इस्तेमाल कैसे कर सकते हैं. अगर आपने शेडर का इस्तेमाल कभी नहीं किया है, तो आगे बढ़ने से पहले आपको इसे पढ़ना ज़रूरी हो जाता है, क्योंकि कस्टम फ़िल्टर के कई कॉन्सेप्ट और भाषा, मौजूदा WebGL शेडर शब्दावली पर निर्भर करते हैं.

तो आइए, कस्टम फ़िल्टर चालू करके इसे चालू करें!

कस्टम फ़िल्टर चालू करना

कस्टम फ़िल्टर Chrome और कैनरी के साथ-साथ Android के लिए Chrome, दोनों में उपलब्ध हैं. बस about:flags पर जाएं और "CSS Shaders" खोजें. इसके बाद, उन्हें चालू करें और ब्राउज़र को रीस्टार्ट करें. अब आप आगे बढ़ने के लिए तैयार हैं!

सिंटैक्स

कस्टम फ़िल्टर, उन फ़िल्टर के सेट से बड़ा हो जाता है जिन्हें आपके DOM एलिमेंट पर पहले से लागू किया जा सकता है. जैसे, blur या sepia. एरिक बिडेलमैन ने उनके लिए एक बेहतरीन प्लेग्राउंड टूल लिखा है, जिसे आपको देखना चाहिए.

किसी DOM एलिमेंट पर कस्टम फ़िल्टर लागू करने के लिए, इस सिंटैक्स का इस्तेमाल करें:

.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)
}

इससे आपको पता चलेगा कि हम अपने वर्टेक्स और फ़्रैगमेंट शेडर को तय करते हैं. साथ ही, उन पंक्तियों और कॉलम की संख्या भी बताते हैं जिन्हें अपने DOM एलिमेंट में बांटना है. इसके बाद, ऐसी किसी भी यूनिफ़ॉर्म का एलान किया जाता है जिसे हम पास करना चाहते हैं.

आखिरी बात यह है कि हम फ़्रैगमेंट शेडर पर mix() फ़ंक्शन का इस्तेमाल ब्लेंड मोड (normal) और कंपोज़िट मोड (source-atop) के साथ करते हैं. आइए, फ़्रैगमेंट शेडर पर नज़र डालते हैं कि हमें mix() फ़ंक्शन की ज़रूरत क्यों है.

पिक्सल पुशिंग

अगर आप WebGL के शेडर के बारे में जानते हैं, तो आपको दिखेगा कि कस्टम फ़िल्टर में, चीज़ें कुछ अलग हैं. उनमें से एक के लिए, हम फ़्रैगमेंट शेडर में पिक्सल भरने के लिए जो टेक्सचर इस्तेमाल करते हैं, हम उन्हें नहीं बनाते. इसके बजाय, जिस DOM कॉन्टेंट में फ़िल्टर लागू किया गया है वह अपने-आप ही किसी टेक्सचर के साथ मैप हो जाता है और इसका मतलब है दो बातें:

  1. सुरक्षा कारणों से हम DOM की बनावट के अलग-अलग पिक्सेल रंग मानों के लिए क्वेरी नहीं कर सकते
  2. हम (कम से कम मौजूदा इंप्लिमेंटेशन में) खुद से फ़ाइनल पिक्सल कलर सेट नहीं करते. इसका मतलब है कि gl_FragColor पर पाबंदी है. इसके बजाय, यह माना जाता है कि आपको DOM कॉन्टेंट को रेंडर करना है. साथ ही, इसके लिए यह माना जाता है कि आपको css_ColorMatrix और css_MixColor के ज़रिए, इसके पिक्सल में सीधे तौर पर बदलाव करना है.

इसका मतलब है कि फ़्रैगमेंट शेडर की हमारी हैलो वर्ल्ड, कुछ ऐसी दिखती है:

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?
}

डीओएम कॉन्टेंट के हर पिक्सल को css_ColorMatrix से गुणा किया जाता है. ऊपर दिए गए मामले में, यह आइडेंटिटी मैट्रिक्स के तौर पर कुछ भी नहीं करता. साथ ही, आरजीबी कॉन्टेंट में से किसी भी वैल्यू में बदलाव नहीं करता है. अगर हम चाहते हैं, तो बस लाल रंग की वैल्यू रखें, हम css_ColorMatrix का इस्तेमाल इस तरह करेंगे:

// 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 (आरजीबीए) पिक्सल की वैल्यू को मैट्रिक्स से गुणा करने पर, आपको दूसरी तरफ़ से बदली गई पिक्सल वैल्यू मिलती है. इस मामले में, यह हरे और नीले रंग के कॉम्पोनेंट को शून्य कर देता है.

css_MixColor का इस्तेमाल मुख्य रूप से ऐसे बेस रंग के तौर पर किया जाता है जिसे आप अपने DOM कॉन्टेंट के साथ मिलाना चाहते हैं. आर्ट पैकेज में मौजूद उन ब्लेंड मोड की मदद से, कॉन्टेंट मिक्स किया जाता है जिनके बारे में आपको पहले से पता होगा. इनमें ओवरले, स्क्रीन, कलर डॉज, हार्ड लाइट वगैरह शामिल हैं.

ये दो वैरिएबल कई तरीकों से पिक्सल में बदलाव कर सकते हैं. ब्लेंड और कंपोज़िट मोड के इंटरैक्ट करने के तरीके को बेहतर तरीके से समझने के लिए, आपको फ़िल्टर इफ़ेक्ट के बारे में खास जानकारी देखनी चाहिए.

Vertex बनाना

WebGL में हम अपने मेश के 3D बिंदुओं के निर्माण की पूरी ज़िम्मेदारी लेते हैं, लेकिन कस्टम फ़िल्टर में आपको बस अपनी पसंद की पंक्तियों और कॉलम की संख्या तय करनी होती है और ब्राउज़र आपकी DOM सामग्री को अपने आप त्रिभुजों के समूह में बांट देगा:

Vertex बनाना
इमेज को पंक्तियों और कॉलम में बांटा जा रहा है

इसके बाद, उनमें से हर शीर्ष को हेर-फेर के लिए, हमारे वर्टेक्स शेडर में पास कर दिया जाता है. इसका मतलब है कि ज़रूरत पड़ने पर हम उन्हें 3D में कहीं भी ले जा सकते हैं. शानदार इफ़ेक्ट तैयार करने में, ज़्यादा समय नहीं लगेगा!

अकॉर्डियन इफ़ेक्ट
एक इमेज को अकॉर्डियन इफ़ेक्ट की मदद से बदला जा रहा है

शेडर के साथ ऐनिमेट करना

शेडर में ऐनिमेशन दिखाना, उन्हें मज़ेदार और दिलचस्प बना देता है. ऐसा करने के लिए, आपको एक जैसी वैल्यू को अपडेट करने के लिए, सीएसएस में बस ट्रांज़िशन (या ऐनिमेशन) का इस्तेमाल करना होगा:

.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);
}

इसलिए, ऊपर दिए गए कोड में ध्यान देने वाली बात यह है कि ट्रांज़िशन के दौरान, 0 से 1 के लिए समय आसान होने वाला है. शेडर के अंदर, हम एक समान time का एलान कर सकते हैं और इसकी मौजूदा वैल्यू का इस्तेमाल कर सकते हैं:

    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;
}

खेलना शुरू करें!

कस्टम फ़िल्टर्स के साथ खेलना मज़ेदार होता है और आपके बनाए जा सकने वाले शानदार प्रभाव उनके बिना कठिन (और कुछ मामलों में नामुमकिन) होते हैं. अभी तो शुरुआत ही हुई है और चीज़ें समय-समय पर बदल रही हैं. अगर आप प्रोजेक्ट जोड़ते हैं, तो इससे आपके प्रोजेक्ट में कुछ नई चीज़ें जुड़ जाती हैं, तो क्यों न आप इन्हें आज़माना शुरू कर दें?

जानकारी पाने के दूसरे तरीके