shaders একটি ভূমিকা

ভূমিকা

আমি পূর্বে আপনাকে Three.js এর একটি ভূমিকা দিয়েছি। যদি আপনি না পড়ে থাকেন যে আপনি এটির ভিত্তি হিসাবে চাইবেন যা আমি এই নিবন্ধের সময় তৈরি করব।

আমি কি করতে চাই shaders আলোচনা. WebGL দারুন, এবং যেমনটি আমি আগেই বলেছি Three.js (এবং অন্যান্য লাইব্রেরি) আপনার জন্য অসুবিধাগুলি দূর করার জন্য একটি দুর্দান্ত কাজ করে। কিন্তু এমন সময় আসবে যে আপনি একটি নির্দিষ্ট প্রভাব অর্জন করতে চান, বা আপনি আপনার স্ক্রিনে কীভাবে সেই আশ্চর্যজনক জিনিসগুলি উপস্থিত হয়েছিল সে সম্পর্কে আপনি একটু গভীরভাবে খনন করতে চাইবেন এবং শেডার্সগুলি অবশ্যই সেই সমীকরণের একটি অংশ হবে। এছাড়াও আপনি যদি আমার মতো হন তবে আপনি শেষ টিউটোরিয়ালের মৌলিক জিনিসগুলি থেকে একটু বেশি জটিল কিছুতে যেতে চাইতে পারেন। আমি যে ভিত্তিতে আপনি Three.js ব্যবহার করছেন তার উপর কাজ করব, যেহেতু এটি শেডার চালু করার ক্ষেত্রে আমাদের জন্য অনেক গাধা কাজ করে। আমি সামনেও বলব যে শুরুতে আমি শেডারের প্রসঙ্গটি ব্যাখ্যা করব এবং এই টিউটোরিয়ালের শেষের অংশটি যেখানে আমরা কিছুটা উন্নত অঞ্চলে প্রবেশ করব। এর কারণ হ'ল শেডার্স প্রথম দর্শনে অস্বাভাবিক এবং কিছুটা ব্যাখ্যা করে।

1. আমাদের দুই শেডার্স

WebGL ফিক্সড পাইপলাইন ব্যবহারের প্রস্তাব দেয় না, যা বলার একটি সংক্ষিপ্ত উপায় যে এটি আপনাকে আপনার জিনিসপত্র বাক্সের বাইরে রেন্ডার করার কোনো উপায় দেয় না। তবে এটি যা দেয় তা হল প্রোগ্রামেবল পাইপলাইন, যা আরও শক্তিশালী কিন্তু বোঝা এবং ব্যবহার করা আরও কঠিন। সংক্ষেপে প্রোগ্রামেবল পাইপলাইন মানে প্রোগ্রামার হিসাবে আপনি শীর্ষবিন্দুগুলি পাওয়ার জন্য দায়িত্ব গ্রহণ করেন এবং তাই পর্দায় রেন্ডার করা হয়। শেডার্স এই পাইপলাইনের একটি অংশ, এবং সেগুলির দুটি প্রকার রয়েছে:

  1. ভার্টেক্স শেডার্স
  2. ফ্র্যাগমেন্ট শেডার্স

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

2. ভার্টেক্স শেডার্স

একটি আদর্শ আদিম আকৃতি নিন, একটি গোলকের মত। এটা শীর্ষবিন্দু গঠিত, তাই না? একটি ভার্টেক্স শেডার এই শীর্ষবিন্দুগুলির মধ্যে প্রতিটি একক দেওয়া হয় এবং সেগুলিকে নিয়ে গোলমাল করতে পারে। এটি ভার্টেক্স শেডারের উপর নির্ভর করে যে এটি প্রতিটিটির সাথে আসলে কী করে, তবে এটির একটি দায়িত্ব রয়েছে: এটি অবশ্যই কিছু সময় gl_Position নামক কিছু সেট করতে হবে, একটি 4D ফ্লোট ভেক্টর, যা স্ক্রিনে শীর্ষবিন্দুর চূড়ান্ত অবস্থান। এটি নিজেই এবং এটি বেশ আকর্ষণীয় প্রক্রিয়া, কারণ আমরা আসলে একটি 2D স্ক্রিনে একটি 3D অবস্থান (x,y,z সহ একটি শীর্ষবিন্দু) পাওয়ার কথা বলছি, বা প্রজেক্ট করা হয়েছে। আমাদের জন্য ধন্যবাদ যদি আমরা Three.js এর মতো কিছু ব্যবহার করি তবে আমাদের কাছে খুব বেশি ভারী না হয়ে gl_Position সেট করার একটি সংক্ষিপ্ত উপায় থাকবে।

3. ফ্র্যাগমেন্ট শেডার্স

সুতরাং আমাদের বস্তুটি তার শীর্ষবিন্দু সহ রয়েছে, এবং আমরা সেগুলিকে 2D স্ক্রিনে প্রজেক্ট করেছি, কিন্তু আমরা যে রঙগুলি ব্যবহার করি তার কী হবে? টেক্সচারিং এবং আলো সম্পর্কে কি? ফ্র্যাগমেন্ট শেডারের জন্য এটি ঠিক কি। অনেকটা ভার্টেক্স শেডারের মতো, ফ্র্যাগমেন্ট শেডারেরও শুধুমাত্র একটি কাজ করতে হবে: এটি অবশ্যই gl_FragColor ভেরিয়েবল সেট বা বাতিল করতে হবে, আরেকটি 4D ফ্লোট ভেক্টর, যা আমাদের খণ্ডের চূড়ান্ত রঙ। কিন্তু একটি খণ্ড কি? তিনটি শীর্ষবিন্দুর কথা চিন্তা করুন যা একটি ত্রিভুজ তৈরি করে। সেই ত্রিভুজের মধ্যে প্রতিটি পিক্সেল আঁকতে হবে। একটি খণ্ড হল সেই ত্রিভুজের প্রতিটি পিক্সেল আঁকার উদ্দেশ্যে সেই তিনটি শীর্ষবিন্দু দ্বারা প্রদত্ত ডেটা। এই কারণে খণ্ডগুলি তাদের উপাদান শীর্ষবিন্দু থেকে ইন্টারপোলেটেড মান গ্রহণ করে। যদি একটি শীর্ষবিন্দু লাল রঙের হয়, এবং এর প্রতিবেশী নীল হয় আমরা দেখতে পাব রঙের মানগুলি লাল থেকে বেগুনি থেকে নীল হয়ে গেছে।

4. Shader ভেরিয়েবল

ভেরিয়েবল সম্পর্কে কথা বলার সময় আপনি তিনটি ঘোষণা করতে পারেন: ইউনিফর্ম , বৈশিষ্ট্য এবং ভিন্নতা । আমি যখন প্রথম এই তিনটির কথা শুনেছিলাম তখন আমি খুব বিভ্রান্ত হয়ে পড়েছিলাম কারণ তারা আমার সাথে কাজ করা অন্য কিছুর সাথে মেলে না। কিন্তু এখানে আপনি কিভাবে তাদের চিন্তা করতে পারেন:

  1. ইউনিফর্মগুলি ভার্টেক্স শেডার এবং ফ্র্যাগমেন্ট শেডার উভয়কেই পাঠানো হয় এবং এতে এমন মান থাকে যা রেন্ডার করা পুরো ফ্রেমে একই থাকে। এর একটি ভাল উদাহরণ একটি আলোর অবস্থান হতে পারে।

  2. গুণাবলী হল মান যা পৃথক শীর্ষবিন্দুতে প্রয়োগ করা হয়। বৈশিষ্ট্যগুলি কেবলমাত্র ভার্টেক্স শেডারে উপলব্ধ। এটি এমন কিছু হতে পারে যা প্রতিটি শীর্ষবিন্দুর একটি স্বতন্ত্র রঙ রয়েছে। শীর্ষবিন্দুগুলির সাথে বৈশিষ্ট্যগুলির একটি এক থেকে এক সম্পর্ক রয়েছে৷

  3. ভেরিয়িং s হল ভার্টেক্স শেডারে ঘোষিত ভেরিয়েবল যা আমরা ফ্র্যাগমেন্ট শেডারের সাথে শেয়ার করতে চাই। এটি করার জন্য আমরা নিশ্চিত করি যে আমরা ভার্টেক্স শেডার এবং ফ্র্যাগমেন্ট শেডার উভয় ক্ষেত্রেই একই ধরণের এবং নামের একটি ভিন্ন পরিবর্তনশীল ঘোষণা করি। এটির একটি ক্লাসিক ব্যবহার একটি শীর্ষবিন্দুর স্বাভাবিক হবে কারণ এটি আলোক গণনায় ব্যবহার করা যেতে পারে।

পরবর্তীতে আমরা তিনটি প্রকার ব্যবহার করব যাতে আপনি অনুভব করতে পারেন যে সেগুলি বাস্তবে কীভাবে প্রয়োগ করা হয়।

এখন আমরা ভার্টেক্স শেডার এবং ফ্র্যাগমেন্ট শেডার এবং তারা যে ধরণের ভেরিয়েবল নিয়ে কাজ করে সে সম্পর্কে কথা বলেছি, এখন আমরা যে সহজতম শেডারগুলি তৈরি করতে পারি তা দেখার মতো।

5. Bonjourno World

এখানে, তারপর, ভার্টেক্স শেডারের হ্যালো ওয়ার্ল্ড:

/**
* Multiply each vertex by the model-view matrix
* and the projection matrix (both provided by
* Three.js) to get a final vertex position
*/
void main() {
gl_Position = projectionMatrix *
                modelViewMatrix *
                vec4(position,1.0);
}   

এবং এখানে ফ্র্যাগমেন্ট শেডারের জন্য একই:

/**
* Set the colour to a lovely pink.
* Note that the color is a 4D Float
* Vector, R,G,B and A and each part
* runs from 0.0 to 1.0
*/
void main() {
gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
}

যদিও খুব জটিল নয়, তাই না?

ভার্টেক্স শেডারে আমরা Three.js দ্বারা কয়েকটি ইউনিফর্ম পাঠানো হয়। এই দুটি ইউনিফর্ম হল 4D ম্যাট্রিক্স, যাকে বলা হয় মডেল-ভিউ ম্যাট্রিক্স এবং প্রজেকশন ম্যাট্রিক্স। এইগুলি কীভাবে কাজ করে তা আপনার মরিয়াভাবে জানার দরকার নেই, যদিও আপনি যদি পারেন তবে জিনিসগুলি কীভাবে তা করে তা বোঝা সর্বদা ভাল। সংক্ষিপ্ত সংস্করণটি হল যে তারা কীভাবে শীর্ষবিন্দুর 3D অবস্থানটি আসলে স্ক্রিনের চূড়ান্ত 2D অবস্থানে অভিক্ষিপ্ত হয়।

আমি আসলে সেগুলি উপরের স্নিপেটের বাইরে রেখে দিয়েছি কারণ Three.js সেগুলিকে আপনার শেডার কোডের শীর্ষে যুক্ত করে তাই আপনাকে এটি করার বিষয়ে চিন্তা করতে হবে না। সত্যই বলা যায় এটি আসলে এর চেয়ে অনেক বেশি যোগ করে, যেমন হালকা ডেটা, শীর্ষবিন্দুর রঙ এবং শীর্ষবিন্দু স্বাভাবিক। আপনি যদি Three.js ছাড়াই এই কাজটি করেন তবে আপনাকে সেই সমস্ত ইউনিফর্ম এবং বৈশিষ্ট্যগুলি তৈরি করতে এবং সেট করতে হবে। সত্য গল্প.

6. একটি MeshShaderMaterial ব্যবহার করা

ঠিক আছে, তাই আমরা একটি শেডার সেট আপ করেছি, কিন্তু কিভাবে আমরা এটি Three.js এর সাথে ব্যবহার করব? দেখা যাচ্ছে যে এটা খুবই সহজ। এটা বরং এই মত:

/**
* Assume we have jQuery to hand and pull out
* from the DOM the two snippets of text for
* each of our shaders
*/
var shaderMaterial = new THREE.MeshShaderMaterial({
vertexShader:   $('vertexshader').text(),
fragmentShader: $('fragmentshader').text()
});

সেখান থেকে Three.js আপনার শেডারগুলিকে কম্পাইল করবে এবং চালাবে জালের সাথে সংযুক্ত যা আপনি সেই উপাদানটি দেবেন। এটা সত্যিই যে তুলনায় অনেক সহজ পেতে না. ঠিক আছে এটি সম্ভবত, কিন্তু আমরা আপনার ব্রাউজারে 3D চালানোর কথা বলছি তাই আমি মনে করি আপনি একটি নির্দিষ্ট পরিমাণ জটিলতা আশা করছেন।

আমরা আসলে আমাদের MeshShaderMaterial-এ আরও দুটি বৈশিষ্ট্য যোগ করতে পারি: ইউনিফর্ম এবং বৈশিষ্ট্য। তারা উভয়ই ভেক্টর, পূর্ণসংখ্যা বা ফ্লোট নিতে পারে তবে আমি আগেই বলেছি ইউনিফর্মগুলি পুরো ফ্রেমের জন্য একই, অর্থাৎ সমস্ত শীর্ষের জন্য, তাই তারা একক মান হতে থাকে। অ্যাট্রিবিউট, যাইহোক, প্রতি-ভার্টেক্স ভেরিয়েবল, তাই তাদের একটি অ্যারে হতে প্রত্যাশিত। অ্যাট্রিবিউট অ্যারেতে মানের সংখ্যা এবং জালের শীর্ষবিন্দুর সংখ্যার মধ্যে এক-এক সম্পর্ক থাকা উচিত।

7. পরবর্তী পদক্ষেপ

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

8. একটি জাল আলো

এর রঙ আপডেট করা যাক যাতে এটি একটি সমতল রঙের বস্তু নয়। আমরা তিন.js কীভাবে আলো পরিচালনা করে তা একবার দেখে নিতে পারি, কিন্তু আমি নিশ্চিত যে আপনি উপলব্ধি করতে পারেন যে এটি এখন আমাদের প্রয়োজনের চেয়ে আরও জটিল, তাই আমরা এটিকে জাল করতে যাচ্ছি। আপনার সম্পূর্ণরূপে দেখতে হবে চমত্কার শেডারগুলি যা Three.js এর একটি অংশ, এবং এছাড়াও ক্রিস মিল্ক এবং Google, রোমের সাম্প্রতিক আশ্চর্যজনক ওয়েবজিএল প্রকল্প থেকে। আমাদের shaders ফিরে. ফ্র্যাগমেন্ট শেডারে প্রতিটি ভার্টেক্স স্বাভাবিক প্রদান করতে আমরা আমাদের ভার্টেক্স শেডার আপডেট করব। আমরা এটি একটি ভিন্নতার সাথে করি:

// create a shared variable for the
// VS and FS containing the normal
varying vec3 vNormal;

void main() {

// set the vNormal value with
// the attribute value passed
// in by Three.js
vNormal = normal;

gl_Position = projectionMatrix *
                modelViewMatrix *
                vec4(position,1.0);
}

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

// same name and type as VS
varying vec3 vNormal;

void main() {

// calc the dot product and clamp
// 0 -> 1 rather than -1 -> 1
vec3 light = vec3(0.5,0.2,1.0);
    
// ensure it's normalized
light = normalize(light);

// calculate the dot product of
// the light to the vertex normal
float dProd = max(0.0, dot(vNormal, light));

// feed into our frag colour
gl_FragColor = vec4(dProd, dProd, dProd, 1.0);

}

তাই ডট প্রোডাক্ট কাজ করার কারণ হল যে দুটি ভেক্টর দেওয়া হলে এটি একটি সংখ্যার সাথে বেরিয়ে আসে যা আপনাকে বলে যে দুটি ভেক্টর কতটা 'সদৃশ'। স্বাভাবিক ভেক্টরের সাথে, যদি তারা ঠিক একই দিকে নির্দেশ করে তবে আপনি 1 এর মান পাবেন। যদি তারা বিপরীত দিকে নির্দেশ করে তবে আপনি একটি -1 পাবেন। আমরা কি করি সেই সংখ্যাটি নিয়ে আমাদের আলোতে এটি প্রয়োগ করি। সুতরাং উপরের ডানদিকে একটি শীর্ষবিন্দুর মান 1 এর কাছাকাছি বা সমান হবে, অর্থাৎ সম্পূর্ণ আলোকিত, যেখানে পাশের একটি শীর্ষের মান 0 এর কাছাকাছি এবং পিছনের বৃত্তাকার হবে -1। আমরা নেতিবাচক কিছুর জন্য মানটিকে 0-এ ক্ল্যাম্প করি, কিন্তু আপনি যখন সংখ্যাগুলি প্লাগ করেন তখন আমরা যে মৌলিক আলো দেখতে পাচ্ছি তার সাথে শেষ হয়।

এরপর কি? ভাল হয়ত কিছু শীর্ষস্থানীয় অবস্থানের সাথে তালগোল পাকানোর চেষ্টা করা ভাল হবে।

9. গুণাবলী

আমি এখন আমাদের যা করতে চাই তা হল একটি বৈশিষ্ট্যের মাধ্যমে প্রতিটি শীর্ষে একটি র্যান্ডম সংখ্যা সংযুক্ত করা। আমরা এই সংখ্যাটি ব্যবহার করব শিরোনামটিকে তার স্বাভাবিক দিকে ঠেলে দিতে। নেট ফলাফল কিছু অদ্ভুত স্পাইক বল হবে যা প্রতিবার পৃষ্ঠাটি রিফ্রেশ করার সময় পরিবর্তিত হবে। এটি এখনও অ্যানিমেটেড করা হবে না (এটি পরবর্তী ঘটবে) তবে কয়েকটি পৃষ্ঠা রিফ্রেশ আপনাকে দেখাবে যে এটি এলোমেলো।

চলুন শুরু করা যাক ভার্টেক্স শেডারে অ্যাট্রিবিউট যোগ করে:

attribute float displacement;
varying vec3 vNormal;

void main() {

vNormal = normal;

// push the displacement into the three
// slots of a 3D vector so it can be
// used in operations with other 3D
// vectors like positions and normals
vec3 newPosition = position + 
                    normal * 
                    vec3(displacement);

gl_Position = projectionMatrix *
                modelViewMatrix *
                vec4(newPosition,1.0);
}

এটা দেখতে কেমন?

সত্যিই খুব আলাদা না! এর কারণ হল মেশশেডার ম্যাটেরিয়ালে অ্যাট্রিবিউটটি সেট আপ করা হয়নি তাই কার্যকরভাবে শেডার পরিবর্তে একটি শূন্য মান ব্যবহার করে। এটা এখন একটি স্থানধারক মত ধরনের. এক সেকেন্ডের মধ্যে আমরা জাভাস্ক্রিপ্টে MeshShaderMaterial-এ অ্যাট্রিবিউট যোগ করব এবং Three.js স্বয়ংক্রিয়ভাবে আমাদের জন্য দুটিকে একসাথে বেঁধে দেবে।

এছাড়াও লক্ষণীয় বিষয় হল যে আমাকে একটি নতুন vec3 ভেরিয়েবলে আপডেট করা অবস্থান বরাদ্দ করতে হয়েছিল কারণ মূল বৈশিষ্ট্য, সমস্ত বৈশিষ্ট্যের মতো, শুধুমাত্র পঠিত।

10. মেশশেডার ম্যাটেরিয়াল আপডেট করা হচ্ছে

আসুন সরাসরি আমাদের মেশশেডার ম্যাটেরিয়ালকে আমাদের স্থানচ্যুতিকে শক্তি দেওয়ার জন্য প্রয়োজনীয় বৈশিষ্ট্যের সাথে আপডেট করার চেষ্টা করি। একটি অনুস্মারক: বৈশিষ্ট্যগুলি প্রতি-উল্লম্ব মান তাই আমাদের গোলক প্রতি শীর্ষে একটি মান প্রয়োজন৷ এটার মত:

var attributes = {
displacement: {
    type: 'f', // a float
    value: [] // an empty array
}
};

// create the material and now
// include the attributes property
var shaderMaterial = new THREE.MeshShaderMaterial({
attributes:     attributes,
vertexShader:   $('#vertexshader').text(),
fragmentShader: $('#fragmentshader').text()
});

// now populate the array of attributes
var vertices = sphere.geometry.vertices;
var values = attributes.displacement.value
for(var v = 0; v < vertices.length; v++) {
values.push(Math.random() * 30);
}

এখন আমরা একটি ম্যাংগলড গোলক দেখছি, কিন্তু চমৎকার জিনিস হল যে সমস্ত স্থানচ্যুতি জিপিইউতে ঘটছে।

11. অ্যানিমেটিং দ্যাট সাকার

আমরা সম্পূর্ণরূপে এই প্রাণবন্ত করা উচিত. কিভাবে আমরা তা করব? ঠিক আছে দুটি জিনিস আমাদের জায়গায় পেতে হবে:

  1. প্রতিটি ফ্রেমে কতটা স্থানচ্যুতি প্রয়োগ করা উচিত তা অ্যানিমেট করার জন্য একটি ইউনিফর্ম। আমরা এর জন্য সাইন বা কোসাইন ব্যবহার করতে পারি যেহেতু তারা -1 থেকে 1 পর্যন্ত চলে
  2. JS এ একটি অ্যানিমেশন লুপ

আমরা MeshShaderMaterial এবং Vertex Shader উভয় ক্ষেত্রেই ইউনিফর্ম যোগ করতে যাচ্ছি। প্রথমে ভার্টেক্স শেডার:

uniform float amplitude;
attribute float displacement;
varying vec3 vNormal;

void main() {

vNormal = normal;

// multiply our displacement by the
// amplitude. The amp will get animated
// so we'll have animated displacement
vec3 newPosition = position + 
                    normal * 
                    vec3(displacement *
                        amplitude);

gl_Position = projectionMatrix *
                modelViewMatrix *
                vec4(newPosition,1.0);
}

পরবর্তী আমরা মেশশেডার ম্যাটেরিয়াল আপডেট করি:

// add a uniform for the amplitude
var uniforms = {
amplitude: {
    type: 'f', // a float
    value: 0
}
};

// create the final material
var shaderMaterial = new THREE.MeshShaderMaterial({
uniforms:       uniforms,
attributes:     attributes,
vertexShader:   $('#vertexshader').text(),
fragmentShader: $('#fragmentshader').text()
});

আমাদের shaders আপাতত সম্পন্ন হয়. কিন্তু ঠিকই আমরা একধাপ পিছিয়ে গিয়েছি বলে মনে হবে। এটি মূলত কারণ আমাদের প্রশস্ততার মান 0 এ এবং যেহেতু আমরা স্থানচ্যুতির সাথে এটিকে গুণ করি আমরা কিছুই পরিবর্তন দেখতে পাচ্ছি না। আমরা অ্যানিমেশন লুপ সেট আপ করিনি তাই আমরা কখনই অন্য কিছুতে 0 পরিবর্তন দেখতে পাই না।

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

var frame = 0;
function update() {

// update the amplitude based on
// the frame value
uniforms.amplitude.value = Math.sin(frame);
frame += 0.1;

renderer.render(scene, camera);

// set up the next call
requestAnimFrame(update);
}
requestAnimFrame(update);

12. উপসংহার

এবং এটাই! আপনি এখন এটি একটি অদ্ভুত (এবং সামান্য trippy) pulsating পদ্ধতিতে অ্যানিমেটিং দেখতে পারেন.

একটি বিষয় হিসাবে আমরা শেডারগুলিতে আরও অনেক কিছু কভার করতে পারি, তবে আমি আশা করি আপনি এই ভূমিকাটি সহায়ক বলে মনে করেছেন। আপনার নিজের কিছু আশ্চর্যজনক শেডার তৈরি করার আত্মবিশ্বাস থাকার সাথে সাথে আপনি যখন সেগুলি দেখবেন তখন আপনি এখন শেডারগুলি বুঝতে সক্ষম হবেন!