কাস্টম ফিল্টারগুলির পরিচিতি (ওরফে CSS শেডার্স)

কাস্টম ফিল্টার, বা CSS শেডার্স যেমন এগুলিকে বলা হত, আপনাকে আপনার DOM সামগ্রীর সাথে WebGL-এর শেডারগুলির শক্তি ব্যবহার করার অনুমতি দেয়৷ যেহেতু বর্তমান বাস্তবায়নে ব্যবহৃত শেডারগুলি কার্যত WebGL-এর মতো একই, তাই আপনাকে একধাপ পিছিয়ে যেতে হবে এবং কিছু 3D পরিভাষা এবং গ্রাফিক্স পাইপলাইনের কিছুটা বুঝতে হবে।

আমি সম্প্রতি লন্ডনজেএস-এ বিতরণ করা একটি উপস্থাপনার একটি রেকর্ড করা সংস্করণ অন্তর্ভুক্ত করেছি। ভিডিওতে আমি 3D পরিভাষাগুলির একটি সংক্ষিপ্ত বিবরণের মাধ্যমে ধাপে ধাপে আপনাকে বুঝতে হবে, বিভিন্ন পরিবর্তনশীল প্রকারগুলি আপনি কী সম্মুখীন হবেন এবং কীভাবে আপনি আজ কাস্টম ফিল্টারগুলির সাথে খেলা শুরু করতে পারেন৷ আপনার স্লাইডগুলিও দখল করা উচিত যাতে আপনি নিজে ডেমোগুলির সাথে খেলতে পারেন৷

Shaders পরিচিতি

আমি আগে শেডারগুলির একটি ভূমিকা লিখেছি যা আপনাকে শেডারগুলি কী এবং আপনি কীভাবে WebGL দৃষ্টিকোণ থেকে সেগুলি ব্যবহার করতে পারেন তার একটি ভাল ব্রেকডাউন দেবে৷ আপনি যদি শেডারগুলির সাথে কখনও ডিল না করে থাকেন তবে আপনি আরও এগিয়ে যাওয়ার আগে এটি একটি প্রয়োজনীয় বিষয়, কারণ কাস্টম ফিল্টারের অনেক ধারণা এবং ভাষা বিদ্যমান WebGL শেডার পরিভাষার উপর নির্ভর করে।

তাই বলেছে, আসুন কাস্টম ফিল্টার সক্ষম করি এবং লাঙ্গল চালু করি!

কাস্টম ফিল্টার সক্রিয় করা হচ্ছে

কাস্টম ফিল্টারগুলি ক্রোম এবং ক্যানারি উভয়ের পাশাপাশি অ্যান্ড্রয়েডের জন্য ক্রোমে উপলব্ধ৷ শুধু about:flags এ যান এবং "সিএসএস শেডার্স" অনুসন্ধান করুন, তাদের সক্ষম করুন এবং ব্রাউজার পুনরায় চালু করুন। এখন আপনি যেতে ভাল!

বাক্য গঠন

কাস্টম ফিল্টারগুলি ফিল্টারের সেটে প্রসারিত হয় যা আপনি ইতিমধ্যেই আপনার 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?
}

DOM বিষয়বস্তুর প্রতিটি পিক্সেল css_ColorMatrix দ্বারা গুণিত হয়, যা উপরের ক্ষেত্রে এটির পরিচয় ম্যাট্রিক্স হিসাবে কিছুই করে না এবং RGBA মানগুলির কোনোটিই পরিবর্তন করে না। যদি আমরা চাই, বলুন, শুধু লাল মান রাখুন আমরা এইরকম একটি 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 (RGBA) পিক্সেল মানগুলিকে ম্যাট্রিক্স দ্বারা গুণ করলে আপনি অন্য দিক থেকে একটি ম্যানিপুলেটেড পিক্সেল মান পাবেন এবং এই ক্ষেত্রে সবুজ এবং নীল উপাদানগুলিকে শূন্য করে দেয়।

css_MixColor প্রধানত একটি বেস রঙ হিসাবে ব্যবহৃত হয় যা আপনি আপনার DOM সামগ্রীর সাথে মিশ্রিত করতে চান। মিশ্রণটি মিশ্রিত মোডগুলির মাধ্যমে করা হয় যা আপনি আর্ট প্যাকেজগুলি থেকে পরিচিত হবেন: ওভারলে, স্ক্রিন, রঙ ডজ, হার্ড লাইট এবং আরও অনেক কিছু।

এই দুটি ভেরিয়েবল পিক্সেলগুলিকে ম্যানিপুলেট করতে পারে এমন প্রচুর উপায় রয়েছে। মিশ্রন এবং যৌগিক মোডগুলি কীভাবে ইন্টারঅ্যাক্ট করে তার একটি ভাল হ্যান্ডেল পেতে আপনার ফিল্টার প্রভাবের স্পেসিফিকেশনটি পরীক্ষা করা উচিত।

ভার্টেক্স সৃষ্টি

WebGL-এ আমরা আমাদের মেশের 3D পয়েন্ট তৈরির সম্পূর্ণ দায়িত্ব নিই, কিন্তু কাস্টম ফিল্টারে আপনাকে যা করতে হবে তা হল আপনি যে সারি এবং কলাম চান তার সংখ্যা নির্দিষ্ট করতে হবে এবং ব্রাউজার স্বয়ংক্রিয়ভাবে আপনার DOM সামগ্রীকে একগুচ্ছ ত্রিভুজে ভেঙে দেবে। :

ভার্টেক্স সৃষ্টি
একটি চিত্র সারি এবং কলামে বিভক্ত করা হচ্ছে৷

এই শীর্ষবিন্দুগুলির প্রত্যেকটি তারপর ম্যানিপুলেশনের জন্য আমাদের ভার্টেক্স শেডারে চলে যায়, এবং এর মানে হল যে আমরা আমাদের প্রয়োজন অনুসারে 3D স্পেসে তাদের ঘুরতে শুরু করতে পারি। আপনি কিছু চমত্কার কল্পিত প্রভাব করতে পারেন আগে এটা দীর্ঘ নয়!

একটি অ্যাকর্ডিয়ন প্রভাব
একটি ছবি একটি অ্যাকর্ডিয়ন প্রভাব দ্বারা বিকৃত করা হচ্ছে৷

Shaders সঙ্গে অ্যানিমেটিং

আপনার শেডারগুলিতে অ্যানিমেশনগুলি আনাই তাদের মজাদার এবং আকর্ষক করে তোলে৷ এটি করার জন্য আপনি অভিন্ন মান আপডেট করতে আপনার CSS-এ একটি ট্রানজিশন (বা অ্যানিমেশন) ব্যবহার করুন:

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

বাজানো পান!

কাস্টম ফিল্টারগুলি খেলতে খুব মজাদার, এবং আপনি যে আশ্চর্যজনক প্রভাবগুলি তৈরি করতে পারেন সেগুলি ছাড়া কঠিন (এবং কিছু ক্ষেত্রে অসম্ভব)। এটি এখনও প্রাথমিক দিন, এবং জিনিসগুলি বেশ খানিকটা পরিবর্তিত হচ্ছে, তবে সেগুলিকে যুক্ত করা আপনার প্রকল্পগুলিতে কিছুটা শোবিজ যোগ করবে, তাহলে কেন সেগুলিকে যেতে দেবেন না?

অতিরিক্ত সম্পদ