ইঞ্জিন রেন্ডারিং পাইপলাইন: শেডারগুলি জেনেরিক করা


10

আমি ওপেনজিএল ইএস ২.০ (আপাতত আইওএস) ব্যবহার করে একটি 2 ডি গেম ইঞ্জিন তৈরি করার চেষ্টা করছি। আমি উদ্দেশ্য সি তে অ্যাপ্লিকেশন স্তর লিখেছি এবং সি ++ এ আলাদা আলাদা রেন্ডারার জিএলএস 20 রয়েছে। রেন্ডারারের বাইরে কোনও জিএল নির্দিষ্ট কল করা হয় না। এটি নিখুঁতভাবে কাজ করছে।

শেডার ব্যবহার করার সময় আমার কাছে কিছু নকশার সমস্যা রয়েছে। প্রতিটি শ্যাডারের নিজস্ব অনন্য বৈশিষ্ট্য এবং ইউনিফর্ম রয়েছে যা মূল ড্র কল (এই ক্ষেত্রে glDrawArrays) এর ঠিক আগে সেট করা দরকার। উদাহরণস্বরূপ, কিছু জ্যামিতি আঁকতে আমি এটি করব:

void RendererGLES20::render(Model * model)
{
    // Set a bunch of uniforms
    glUniformMatrix4fv(.......);
    // Enable specific attributes, can be many
    glEnableVertexAttribArray(......);
    // Set a bunch of vertex attribute pointers:
    glVertexAttribPointer(positionSlot, 2, GL_FLOAT, GL_FALSE, stride, m->pCoords);

    // Now actually Draw the geometry
    glDrawArrays(GL_TRIANGLES, 0, m->vertexCount);

    // After drawing, disable any vertex attributes:
    glDisableVertexAttribArray(.......);
}

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

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

অভিনেতা শ্রেণীর নিম্নলিখিত শো:

class Actor : public ISceneNode
{
    ModelController * model;
    AIController * AI;
};

মডেল কন্ট্রোলার ক্লাস: ক্লাস মডেলকন্ট্রোলার {শ্রেণি ইশাদার * শেডার; int টেক্সচারআইড; vec4 আভা; ভাসা আলফা; স্ট্রাক্ট ভার্টেক্স * ভার্টেক্সআরে; };

শেডার শ্রেণিতে শ্যাডার অবজেক্ট, সংকলন এবং উপ-রুটিনগুলি সংযুক্তকরণ ইত্যাদি রয়েছে just

গেম লজিক ক্লাসে আমি আসলে অবজেক্টটি রেন্ডার করছি:

void GameLogic::update(float dt)
{
    IRenderer * renderer = g_application->GetRenderer();

    Actor * a = GetActor(id);
    renderer->render(a->model);
}

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

এই উন্নতি করতে কোন ধারণা? সম্পর্কিত নকশা নিদর্শন ইত্যাদি?

প্রশ্নটি পড়ার জন্য আপনাকে ধন্যবাদ।



এটি হুবহু নকল কিনা তা নিশ্চিত নন তবে আপনি যা করার চেষ্টা করছেন তা মাংসের কাছে পৌঁছে যায় বলে আমি মনে করি।
শান মিডলডিচ

উত্তর:


12

আপনার শেডার সিস্টেমটিকে আরও ডেটা-চালিত করে তোলা সম্ভব, যাতে আপনার ইউনিফর্ম এবং ভার্টেক্স ফর্ম্যাটের জন্য শেডার-নির্দিষ্ট কোড না রাখার পরিবর্তে শেডারের সাথে সংযুক্ত মেটাডেটার ভিত্তিতে প্রোগ্রামিকভাবে সেট করুন।

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

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

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

এটি করার বিভিন্ন উপায় রয়েছে; উদাহরণস্বরূপ, শেডারের বৈশিষ্ট্যগুলির জন্য আপনার নামগুলির একটি স্ট্যান্ডার্ড সেট থাকতে পারে ("অ্যাট্রিপজিশন", "অ্যাটর্নরমাল", ইত্যাদি) এবং কিছু হার্ড-কোডেড নিয়ম যেমন "পজিশনটি 3 ফ্লোট"। তারপরে আপনি glGetAttribLocationশেডার যেগুলি ব্যবহার করে তার বৈশিষ্ট্যগুলি জিজ্ঞাসা করতে ব্যবহার করুন বা সিম্পায়ার করুন এবং ভার্টেক্স বিন্যাসটি তৈরি করতে নিয়মগুলি প্রয়োগ করুন। আরেকটি উপায় হ'ল একটি এক্সএমএল স্নিপেটটি ফর্ম্যাটটি সংজ্ঞায়িত করা হয়েছে, শেডার উত্সের একটি মন্তব্যে এম্বেড করা হয়েছে এবং আপনার সরঞ্জামগুলি দ্বারা সন্ধান করা হয়েছে বা সেই লাইন বরাবর কিছু রয়েছে।

ইউনিফর্মগুলির জন্য, আপনি যদি ওপেনজিএল 3.1 ব্যবহার করতে পারেন বা তার পরে ইউনিফর্ম বাফার অবজেক্টগুলি (ডি 3 ডি এর ধ্রুবক বাফারের সমতুল্য ওপেনজিএল) ব্যবহার করা ভাল ধারণা । হায়, জিএল ইএস ২.০ এগুলি নেই, তাই ইউনিফর্মগুলি পৃথকভাবে পরিচালনা করতে হবে। এটি করার একটি উপায় হ'ল আপনি যে প্যারামিটারটি সেট করতে চান তার জন্য অভিন্ন অবস্থান সম্বলিত একটি কাঠামো তৈরি করা হবে - ক্যামেরা ম্যাট্রিক্স, স্পেকুলার পাওয়ার, ওয়ার্ল্ড ম্যাট্রিক্স ইত্যাদি amp এই অ্যাড্রেসটি সমস্ত শেডারগুলিতে ভাগ করা প্যারামিটারগুলির একটি মানক সেট থাকার উপর নির্ভর করে। প্রতিটি শেডারকে প্রতিটি একক প্যারামিটার ব্যবহার করতে হয় না, তবে সমস্ত প্যারামিটারগুলি এই স্ট্রাক্টে থাকতে হবে।

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.