একাধিক জিএলএসএল শেডারগুলির মধ্যে ভাগ করে নেওয়ার কোড


30

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

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

ডিআরওয়াই রাখার জন্য কি কোনও গৃহীত সেরা অনুশীলন রয়েছে ? লোকেরা কি তাদের সমস্ত শেডারে কেবল একটি একক প্রচলিত ফাইল প্রস্তুত করে? তারা কি তাদের নিজস্ব সি-স্টাইলের প্রিপ্রোসেসর লিখেন যা #includeনির্দেশকে পার্স করে ? শিল্পে যদি স্বীকৃত নিদর্শন থাকে তবে আমি সেগুলি অনুসরণ করতে চাই।


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

2
হুম, আমার কাছে ভাল লাগছে। আমি বলব যে স্ট্যাক ওভারফ্লো প্রবাহের চেয়ে আমরা আমাদের প্রশ্নগুলিতে কিছুটা "বিস্তৃত" / "আরও সাধারণ" আছি।
ক্রিস বলছেন মনিকাকে st ই

2
স্ট্যাকওভারফ্লো একটি 'আমাদের জিজ্ঞাসা করুন' হয়ে গিয়েছিল 'আপনাকে সন্তুষ্ট করতে না চাইলে আমাদের জিজ্ঞাসা করবেন না ' বোর্ডে।
ইনসাইডিন

যদি এটি অন-টপিকটি নির্ধারণের উদ্দেশ্যে হয় তবে কীভাবে সম্পর্কিত মেটা প্রশ্ন সম্পর্কে?
এসএল বার্থ - মনিকা পুনরায়

উত্তর:


18

অনেকগুলি পন্থা রয়েছে তবে কোনওটিই নিখুঁত নয়।

glAttachShaderশেডারগুলিকে একত্রিত করে কোড ভাগ করা সম্ভব , তবে এটি স্ট্রাক্ট ডিক্লেয়ারেশন বা- #defineডি কনস্ট্যান্টের মতো জিনিসগুলি ভাগ করা সম্ভব করে না । এটি ফাংশন ভাগ করে নেওয়ার জন্য কাজ করে।

কিছু লোক glShaderSourceআপনার কোডের আগে সাধারণ সংজ্ঞা সংশোধন করার উপায় হিসাবে পাস করা স্ট্রিংগুলির অ্যারে ব্যবহার করতে পছন্দ করে তবে এর কিছু অসুবিধা রয়েছে:

  1. শেডারের মধ্যে যা অন্তর্ভুক্ত করা দরকার তা নিয়ন্ত্রণ করা আরও শক্ত (আপনার এটির জন্য একটি পৃথক সিস্টেমের প্রয়োজন))
  2. এর অর্থ শ্যাডার লেখক জিএলএসএল নির্দিষ্ট করতে পারবেন না, জিএলএসএল অনুচ্ছেদে #versionনিম্নলিখিত বিবৃতিটির কারণে:

#Version নির্দেশক, অন্য কিছু আগে একটি shader ঘটা উচিত মতামত ও সাদা স্থান ছাড়া।

এই বিবৃতিটির কারণে glShaderSource, #versionঘোষণার আগে পাঠ্য পুনরায় চাপতে ব্যবহার করা যাবে না । এর অর্থ হ'ল #versionলাইনটি আপনার glShaderSourceযুক্তিগুলিতে অন্তর্ভুক্ত করা দরকার , যার অর্থ আপনার জিএলএসএল সংকলক ইন্টারফেসটি কোনওভাবে জিএলএসএল এর কোন সংস্করণ ব্যবহার করা হবে বলে আশা করা উচিত। অতিরিক্ত হিসাবে, একটি নির্দিষ্ট করে না#version করে GLSL সংস্করণ 1.10 ব্যবহার করে GLSL সংকলককে ডিফল্ট করে তুলবে। আপনি যদি শেডার লেখককে #versionস্ক্রিপ্টের মধ্যে একটি স্ট্যান্ডার্ড উপায়ে নির্দিষ্ট করতে চান , তবে আপনাকে বিবৃতি #includeদেওয়ার পরে কোনওভাবে সন্নিবেশ করাতে হবে #version#versionস্ট্রিংটি খুঁজে পেতে (উপস্থিত থাকলে) পরিষ্কারভাবে জিএলএসএল শেডারকে বিশ্লেষণ করে এর পরে আপনার অন্তর্ভুক্তি তৈরি করার মাধ্যমে এটি করা যেতে পারে, তবে একটিতে অ্যাক্সেস থাকা#includeযখন এই অন্তর্ভুক্তিগুলি করা দরকার তখন নির্দেশিকা আরও সহজেই নিয়ন্ত্রণ করা আরও ভাল। অন্যদিকে, যেহেতু জিএলএসএল #versionলাইনের আগে মন্তব্যগুলিকে উপেক্ষা করে, তাই আপনার ফাইলের শীর্ষে মন্তব্যগুলির মধ্যে অন্তর্ভুক্ত করার জন্য আপনি মেটাডেটা যুক্ত করতে পারেন (ইয়াক।)

এখন প্রশ্নটি হল: এর কোনও মানক সমাধান আছে কি? #include , নাকি আপনার নিজের প্রিপ্রসেসর এক্সটেনশন রোল করার দরকার আছে?

নেই GL_ARB_shading_language_includeএক্সটেনশন, কিন্তু এটি কিছু অপূর্ণতা আছে:

  1. এটি কেবল এনভিআইডিআইএ দ্বারা সমর্থিত ( http://delphigl.de/glcapsviewer/listreports2.php?listreportsbyexistance=GL_ARB_Sading_language_incolve )
  2. এটি সময়ের আগে অন্তর্ভুক্ত স্ট্রিংগুলি নির্দিষ্ট করে কাজ করে। সুতরাং, সংকলনের আগে, আপনাকে অবশ্যই উল্লেখ করতে হবে যে স্ট্রিংটি "/buffers.glsl"(যেমন ব্যবহৃত হয়েছে #include "/buffers.glsl") ফাইলের সামগ্রীর সাথে সামঞ্জস্য করে buffer.glsl(যা আপনি আগে লোড করেছেন)।
  3. আপনি যেমন পয়েন্ট (2) এ লক্ষ্য করেছেন, আপনার পাথগুলি "/"লিনাক্স-স্টাইলের পরম পাথগুলির মতো শুরু হওয়া দরকার । এই স্বরলিপিটি সাধারণত সি প্রোগ্রামারদের কাছে অপরিচিত এবং এর অর্থ আপনি আপেক্ষিক পাথ নির্দিষ্ট করতে পারবেন না।

একটি সাধারণ নকশা হ'ল আপনার নিজস্ব #includeপ্রক্রিয়াটি বাস্তবায়ন করা , তবে এটি জটিল হতে পারে যেহেতু #ifশর্তসাপেক্ষ সংকলন (শিরোনাম রক্ষীদের মতো) সঠিকভাবে পরিচালনা করার জন্য আপনাকে অন্যান্য প্রাক প্রসেসর নির্দেশিকাগুলিও পার্স (এবং মূল্যায়ন) করতে হবে)

আপনি যদি নিজের প্রয়োগ করে #includeথাকেন তবে কীভাবে আপনি এটি বাস্তবায়ন করতে চান তাতে আপনার কিছু স্বাধীনতাও রয়েছে:

  • আপনি সময়ের আগে স্ট্রিং পাস করতে পারেন (পছন্দ GL_ARB_shading_language_include)।
  • আপনি একটি অন্তর্ভুক্ত কলব্যাক নির্দিষ্ট করতে পারেন (এটি ডাইরেক্টএক্সের ডি 3 ডিকম্পিলার লাইব্রেরি দ্বারা সম্পন্ন করা হয়েছে))
  • আপনি এমন একটি সিস্টেম প্রয়োগ করতে পারেন যা সাধারন সি অ্যাপ্লিকেশনগুলির মতো সর্বদা সরাসরি ফাইল সিস্টেম থেকে পড়ে।

সরলকরণ হিসাবে, আপনি নিজের প্রিপ্রসেসিং লেয়ারের অন্তর্ভুক্ত প্রত্যেকটির জন্য স্বয়ংক্রিয়ভাবে শিরোনাম রক্ষক সন্নিবেশ করতে পারেন, যাতে আপনার প্রসেসরের স্তরটি দেখতে দেখতে এমন হয়:

if (#include and not_included_yet) include_file();

(আমাকে উপরের কৌশলটি দেখানোর জন্য ক্রেডিট টু ট্রেন্ট রিড))

উপসংহারে , কোনও স্বয়ংক্রিয়, মানক এবং সহজ সমাধান নেই। ভবিষ্যতের সমাধানে আপনি কিছু এসপিআইআর-ভি ওপেনজিএল ইন্টারফেস ব্যবহার করতে পারেন, সেক্ষেত্রে জিপিএসএল থেকে এসপিআইআর-ভি সংকলক জিএল এপিআই-র বাইরে থাকতে পারে। ওপেনএলএল রানটাইমের বাইরে সংকলকটি থাকা বিষয়গুলি প্রয়োগ করা সহজতর করে তোলে #includeযেহেতু এটি ফাইল সিস্টেমের সাথে ইন্টারফেস করার জন্য উপযুক্ত স্থান। আমি বিশ্বাস করি যে বর্তমানের বিস্তৃত পদ্ধতিটি কেবলমাত্র একটি কাস্টম প্রিপ্রসেসর বাস্তবায়ন করা যা কোনও সি প্রোগ্রামার সাথে পরিচিত হওয়া উচিত way


শেডারগুলি glslify ব্যবহার করে মডিউলগুলিতে পৃথক করা যায় , যদিও এটি কেবল নোড.জেএস দিয়ে কাজ করে though
অ্যান্ডারসন সবুজ

9

আমি সাধারণত কেবল সত্যটি ব্যবহার করি যে glShaderSource (...) স্ট্রিংগুলির একটি অ্যারেটিকে ইনপুট হিসাবে গ্রহণ করে।

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

কেবল যোগ করার জন্য, এএফআইএকি, অবাস্তব ইঞ্জিন 4 একটি # অন্তর্ভুক্ত নির্দেশিকা ব্যবহার করে যা সংশ্লেষের পূর্বে, যেমনটি আপনি পরামর্শ দিয়েছিলেন, পার্স হয়ে যায় এবং সমস্ত প্রাসঙ্গিক ফাইল সংযুক্ত করে।


4

আমি মনে করি না যে এখানে একটি সাধারণ সম্মেলন রয়েছে, তবে আমি যদি অনুমান করি তবে আমি বলতে পারি যে প্রায় প্রত্যেকে প্রিপ্রোসেসিং পদক্ষেপ (একটি #includeএক্সটেনশন) হিসাবে পাঠ্যগত অন্তর্ভুক্তির কিছু সাধারণ ফর্ম প্রয়োগ করে , কারণ এটি করা খুব সহজ তাই। (জাভাস্ক্রিপ্ট / ওয়েবজিএলে আপনি উদাহরণস্বরূপ একটি সাধারণ নিয়মিত-এক্সপ্রেশন দিয়ে এটি করতে পারেন)। এর বিপরীতটি হ'ল আপনি "রিলিজ" তৈরির জন্য একটি অফলাইন ধাপে প্রিপ্রসেসিং সম্পাদন করতে পারেন, যখন শেডার কোডটি আর পরিবর্তন করার প্রয়োজন নেই।

আসলে, একটি ইঙ্গিত যে এই পদ্ধতির সাধারণ সত্য যে একটি ARB এক্সটেনশন যে জন্য চালু করা হয় হয়: GL_ARB_shading_language_include। আমি এখনই নিশ্চিত নই যে এটি এখনই না মূল বৈশিষ্ট্য হয়ে উঠেছে, তবে এক্সটেনশনটি ওপেনজিএল 3.2 এর বিপরীতে লেখা হয়েছিল।


2
জিএল_আরবি_স্যাডিং_লংগুয়েজ_মিনেজ কোনও মূল বৈশিষ্ট্য নয়। আসলে, কেবল এনভিআইডিএই এটি সমর্থন করে। ( delphigl.de/glcapsviewer/… )
নিকোলাস লুই

4

কিছু লোক ইতিমধ্যে চিহ্নিত করেছে যে glShaderSourceস্ট্রিংগুলির একটি অ্যারে নিতে পারে।

তার উপরে, জিএলএসএল-এ শ্যাডারের সংকলন ( glShaderSource, glCompileShader) এবং লিঙ্কিং ( glAttachShader, glLinkProgram) পৃথক।

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

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

শেষ পর্যন্ত এই কৌশলটি কিছু ডিআরওয়াই বিষয়গুলিকে সম্বোধন করে তবে এটি আদর্শ থেকে দূরে।

এক পক্ষের বিষয়ে, আমি নিশ্চিত নই যে এই পদ্ধতির সংকলনের সময়ের ক্ষেত্রে কোনও প্রভাব আছে কিনা; আমি পড়েছি যে কিছু ড্রাইভার কেবল লিঙ্কিংয়ের সাথে শেডার প্রোগ্রামটি সত্যই সংকলন করে, তবে আমি মাপা হয়নি।


আমার বোঝাপড়া থেকে, আমি মনে করি এটি স্ট্রাক্ট সংজ্ঞাগুলি ভাগ করার সমস্যাটিকে সমাধান করে না।
নিকোলাস লুই গুইলমোট

@ নিকোলাসলুইস গুইলমোট: হ্যাঁ আপনি ঠিক বলেছেন, নির্দেশাবলীর কোডটি এভাবেই ভাগ করা হয়, ঘোষণা নয়।
জুলিয়েন গের্টল্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.