একটি আধা-সাধারণ পদ্ধতির মধ্যে আমি শেডার উপাদানগুলিকে যা বলি তা করা, আমি মডিউলগুলিকে কল করছি বলে মনে করি তার অনুরূপ।
ধারণাটি পোস্ট-প্রসেসিং গ্রাফের মতো। আপনি শেডার কোডের খণ্ডগুলি লিখুন এতে প্রয়োজনীয় ইনপুট, উত্পন্ন আউটপুট এবং তারপরে কোডটি আসলে এতে কাজ করতে পারে। আপনার কাছে একটি তালিকা রয়েছে যা কোন পরিস্থিতিতে কোন ছায়ারগুলিকে প্রয়োগ করতে হবে তা বোঝায় (এই উপাদানটির কোনও টোল ম্যাপিং উপাদান দরকার কিনা, পিছিয়ে দেওয়া বা ফরোয়ার্ড উপাদান সক্ষম করা আছে কিনা ইত্যাদি)।
আপনি এখন এই গ্রাফটি নিতে এবং এটি থেকে শেডার কোড তৈরি করতে পারেন। এর বেশিরভাগটির অর্থ হ'ল খণ্ডের কোডটি স্থানান্তরিত করা; গ্রাফটি নিশ্চিত করা হয়েছে যে তারা প্রয়োজনীয় ক্রমে ইতিমধ্যে রয়েছে এবং তারপরে শেডার ইনপুট / আউটপুটগুলিকে যথাযথভাবে আটকানো হয়েছে (জিএলএসএল-এ, এর অর্থ আপনার "গ্লোবাল" সংজ্ঞায়িত করা হয়েছে , আউট এবং অভিন্ন ভেরিয়েবল))
এটি একটি উবারশাদার পদ্ধতির মতো নয়। উবারশাদাররা হলেন আপনি যেখানে সমস্ত কিছুর জন্য প্রয়োজনীয় সমস্ত কোডকে এক এক শেডারে শেডের মধ্যে রেখেছেন, সম্ভবত #ifdefs এবং ইউনিফর্ম ব্যবহার করে এবং সংকলন বা চালনার সময় বৈশিষ্ট্যগুলি চালু এবং বন্ধ করতে চান। আমি ব্যক্তিগতভাবে উবারশেদার পদ্ধতির তীব্রতাকে তুচ্ছ করি, তবে কিছু পরিবর্তে চিত্তাকর্ষক এএএ ইঞ্জিনগুলি সেগুলি ব্যবহার করে (বিশেষ করে ক্রিটেকের মনে আসে)।
আপনি বিভিন্ন উপায়ে শেডার খণ্ডগুলি পরিচালনা করতে পারেন। সর্বাধিক উন্নত উপায় - এবং যদি আপনি জিএলএসএল, এইচএলএসএল এবং কনসোলগুলি সমর্থন করার পরিকল্পনা করেন তবে দরকারী - শেডার ভাষার জন্য একটি পার্সার লিখতে হয় (সম্ভবত এইচএলএসএল / সিজি বা জিএলএসএল এর কাছাকাছি যতটা সম্ভব আপনার ডিভসের দ্বারা "বোধগম্যতা" পেতে পারেন) ) যা উত্স থেকে উত্স অনুবাদগুলির জন্য ব্যবহার করা যেতে পারে। আর একটি পদ্ধতি হ'ল এক্সএমএল ফাইলগুলিতে শেডার খণ্ডগুলি গুছিয়ে রাখা বা যেমন, যেমন
<shader name="example" type="pixel">
<input name="color" type="float4" source="vertex" />
<output name="color" type="float4" target="output" index="0" />
<glsl><![CDATA[
output.color = vec4(input.color.r, 0, 0, 1);
]]></glsl>
</shader>
এই পদ্ধতির সাথে নোট করুন আপনি বিভিন্ন API বা এমনকি সংস্করণ কোড বিভাগের জন্য একাধিক কোড বিভাগ তৈরি করতে পারেন (যাতে আপনার একটি GLSL 1.20 সংস্করণ এবং একটি GLSL 3.20 সংস্করণ থাকতে পারে)। আপনার গ্রাফ এমনকি স্বয়ংক্রিয়ভাবে শেডার খণ্ডগুলি বাদ দিতে পারে যার কোনও সামঞ্জস্যপূর্ণ কোড বিভাগ নেই যাতে আপনি পুরানো হার্ডওয়ারের উপর আধা-গারফুল অবক্ষয় পেতে পারেন (সুতরাং সাধারণ ম্যাপিংয়ের মতো কিছু বা পুরানো হার্ডওয়্যারে কেবল বাদ দেওয়া হয়েছে যা প্রোগ্রামার প্রয়োজন ছাড়াই এটি সমর্থন করতে পারে না) একগুচ্ছ স্পষ্ট চেক করুন)।
এক্সএমএল নমুনা এর পরে অনুরূপ কিছু উত্পন্ন করতে পারে (ক্ষমা প্রার্থনা করুন যদি এটি অবৈধ জিএলএসএল হয় তবে এটির কিছুক্ষণ হয়ে গেলো যেহেতু আমি নিজেকে সেই এপিআইতে বশীভূত করেছি):
layout (location=0) in vec4 input_color;
layout (location=0) out vec4 output_color;
struct Input {
vec4 color;
};
struct Output {
vec4 color;
}
void main() {
Input input;
input.color = input_color;
Output output;
// Source: example.shader
#line 5
output.color = vec4(input.color.r, 0, 0, 1);
output_color = output.color;
}
আপনি কিছুটা চৌকস হয়ে উঠতে পারেন এবং আরও "দক্ষ" কোড তৈরি করতে পারেন, তবে সত্যই যে কোনও শেডার সংকলক সম্পূর্ণ বকাবকি নয় তা আপনার জন্য উত্পন্ন কোড থেকে অপ্রয়োজনীয়তা সরিয়ে ফেলবে। হয়তো আরও নতুন জিএলএসএল আপনাকে #line
এখন ফাইলের নাম কমান্ডে রাখতে দেয় , তবে আমি জানি যে পুরানো সংস্করণগুলি খুব ঘাটতি এবং এটি সমর্থন করে না।
আপনার যদি একাধিক খণ্ড থাকে তবে তাদের ইনপুটগুলি (যা গাছের পূর্বপুরুষের দ্বারা আউটপুট হিসাবে সরবরাহ করা হয় না) আউটপুটগুলির মতো ইনপুট ব্লকে সংক্ষিপ্ত করে দেওয়া হয় এবং কোডটি কেবল সংক্ষেপিত হয়। পর্যায়গুলি মেলে (ভার্টেক্স বনাম খণ্ড) এবং সেই প্রান্তিক বৈশিষ্ট্য ইনপুট লেআউটগুলি "কেবলমাত্র কাজ করে" তা নিশ্চিত করার জন্য কিছুটা অতিরিক্ত কাজ করা হয়। এই পদ্ধতির সাথে আরেকটি দুর্দান্ত সুবিধা হ'ল আপনি স্বচ্ছ ইউনিফর্ম এবং ইনপুট অ্যাট্রিবিউট বন্ডিং সূচকগুলি লিখতে পারেন যা GLSL এর পুরানো সংস্করণগুলিতে অসমর্থিত এবং এগুলি আপনার শেডার জেনারেশন / বাইন্ডিং লাইব্রেরিতে পরিচালনা করতে পারেন। অনুরূপভাবে আপনি আপনার ভিবিও এবং glVertexAttribPointer
কলগুলি সেট আপ করার ক্ষেত্রে মেটাডেটা ব্যবহার করতে পারবেন এবং সামঞ্জস্যতা নিশ্চিত করতে এবং "সবকিছু কেবল" কাজ করে।
দুর্ভাগ্যক্রমে ইতিমধ্যে এর মতো ভাল ক্রস-এপিআই লাইব্রেরি নেই। সিজি কিছুটা কাছাকাছি আসে, তবে এটিএমডি কার্ডগুলিতে ওপেনজিএলের পক্ষে ক্রেপ সমর্থন করে এবং আপনি যদি সর্বাধিক বেসিক কোড জেনারেশন বৈশিষ্ট্যগুলি ব্যবহার করেন তবে অত্যন্ত ধীর হতে পারে। ডাইরেক্টএক্স এফেক্টস ফ্রেমওয়ার্কটি খুব কাজ করে তবে অবশ্যই এইচএলএসএল ছাড়া যে কোনও ভাষার জন্য শূন্য সমর্থন রয়েছে। জিএলএসএল-এর জন্য কিছু অসম্পূর্ণ / বগি লাইব্রেরি রয়েছে যা ডাইরেক্টএক্স গ্রন্থাগারগুলিকে নকল করে তবে তাদের রাজ্যটি শেষবার যখন আমি পরীক্ষা করেছিলাম আমি কেবল নিজের লেখা লিখি।
উবারশাদার পদ্ধতির অর্থ কেবলমাত্র কিছু বৈশিষ্ট্যগুলির জন্য "সুপরিচিত" প্রিপ্রোসেসর নির্দেশিকাগুলি সংজ্ঞায়িত করা এবং তারপরে বিভিন্ন কনফিগারেশন সহ বিভিন্ন উপকরণের জন্য পুনরায় সংযোগ করা। উদাহরণস্বরূপ, সাধারণ মানচিত্র সহ যে কোনও উপাদানের জন্য আপনি সংজ্ঞায়িত করতে পারেন USE_NORMAL_MAPPING=1
এবং তারপরে আপনার পিক্সেল-পর্যায়ে উবারশাদারে কেবলমাত্র:
#if USE_NORMAL_MAPPING
vec4 normal;
// all your normal mapping code
#else
vec4 normal = normalize(in_normal);
#endif
এখানে একটি বড় সমস্যা হ'ল প্রাকম্পম্পিল্ড এইচএলএসএল-এর জন্য এটি পরিচালনা করছে, যেখানে আপনাকে ব্যবহারের সমস্ত সংমিশ্রণ প্রাক্পম্পাইল করতে হবে। এমনকি জিএলএসএল-এর সাথে অভিন্ন ছায়া গোছানো / ক্যাচিং এড়ানোর জন্য আপনার সমস্ত প্রিপ্রসেসর নির্দেশাবলীর একটি কী সঠিকভাবে উত্পন্ন করতে সক্ষম হতে হবে। ইউনিফর্ম ব্যবহার জটিলতা হ্রাস করতে পারে তবে প্রাক-প্রসেসর ইউনিফর্মগুলির বিপরীতে নির্দেশনা গণনা হ্রাস করে না এবং এখনও পারফরম্যান্সে কিছুটা ছোট প্রভাব ফেলতে পারে।
কেবল স্পষ্ট করে বলতে গেলে, উভয় পন্থা (পাশাপাশি কেবল ম্যানুয়ালি শেডারের বিভিন্ন ধরণের বৈচিত্রগুলি লিখতে) সমস্তই এএএ স্পেসে ব্যবহৃত হয়। আপনার জন্য যেটি ভাল কাজ করে তা ব্যবহার করুন।