بازی و سرگرمی

گیمولوژی | رسانه تحلیلی بازی سازی | شیدر نویسی در یونیتی (بخش دوم)

قبل از شروع شیدر نویسی بهتر است به چند سوال متداول پاسخ دهیم:

شیدر چیست و چه لزومی دارد که از آنها استفاده کنیم؟

 شیدر برنامه‌ای است که به طور خاص روی یک GPU اجرا و از آن‌ها، برای دستکاری آن چه روی صفحه نمایش توسط کارت گرافیک ارائه شده  استفاده می‌شود. از آنجایی که این برنامه‌های کوچک در واقع روی کارت  گرافیک اجرا می‌شوند، به این معنی است که آنها برای پردازش بسیار سریع هستند و لزوم استفاده‌ی آنها، برای آزاد سازی چرخه ارزشمند CPU برای منطق بازی است.

چه نیازی به یادگیری شیدرنویسی داریم در صورتی که می توانیم از شیدر های آماده و پیش فرض استفاده کنیم؟

یادگیری شیدرنویسی به شما کمک می‌کند که علاوه بر نوشتن شیدر ، قدرت شخصی‌سازی شیدر های بازی‌تان را نیز داشته باشید و بنا بر نیازتان، ویژگی‌هایی را به آن اضافه و یا از آن کم کنید. هر چند شما می‌توانید از شیدرهای پیش‌فرض و یا آماده استفاده کنید، اما گاهی لازم است که برای منحصربه‌فرد کردن بازی‌تان شیدری خاص بنویسید. همان طور که استفاده‌ی بیش از حد کدهای آماده در بازی توصیه نمی‌شود، بهتر است خیلی زیاد از شیدرهای آماده استفاده نکنید. یکی از عواملی که باعث می‌شود بازی‌تان جذاب‌تر شود، استفاده از شیدرها و افکت‌های جدید است؛ پس بهتر است از کنار آن به آسانی عبور نکنید.

تعاریف شیدر، متریال و تسکچر

شیدر یک کد است که رفتار نورپردازی و ویژگی‌های رندر آبجکت یا افکت‌های دوربین را توصیف می‌کند اما متریال تعیین می‌کند که چگونه یک سطح باید رندر شود. متریال‌ها می‌توانند داده‌های مختلفی را برحسب نیاز سایه‌زن در خود نگه دارند از جمله رفرنس بافت استفاده شده، اطلاعات کاشی کاری (Tiling Information)، رنگ و غیره .

بافت‌ها (Textures) تصاویر Bitmap هستند. یک متریال ممکن است رفرنس به یک بافت داشته باشد به طوری که شیدرِ متریال در هنگام محاسبه می‌تواند رنگ سطحی یک شی را از بافت‌ها استفاده کند. علاوه بر رنگ پایه (Albedo)، بافت‌ها می توانند بسیاری از جنبه‌های دیگر سطح متریال مانند زبر و مات یا صیقلی و براق بودن را تعیین کنند.

نکات:

– گزینه‌های موجود در یک متریال بستگی به شیدر استفاده شده در متریال دارند. شیدر یک یا چند متغیر بافتی که انتظار می‌رود استفاده شود را مشخص می‌کند و Inspector Material  در Unity به شما اجازه می‌دهد که ورودی‌های بافت خود را به این متغیرهای بافت اختصاص دهید.

– اين نكته را مد نظر قرار دهید که شیدرها اغلب برای کنترل نور و اثرات سایه‌ای استفاده می‌شوند اما هیچ دلیلی وجود ندارد که توانایی آن‌ها به همین موارد محدود شود.

آیا دانستن برنامه‌نویسی برای نوشتن شیدر امری ضروری است؟ زبان شیدر نویسی در یونیتی چیست؟

برای شروع شیدر نویسی بهتر است مشکلی در برنامه‌نویسی نداشته باشید تا مسیر برای‌تان هموارتر گردد. یادگیری زبان شیدر مانند روال یادگیری زبان برنامه‌نویسی جدید است. مفاهیم زبان‌های برنامه‌نویسی تقریباً یکسان است؛ بنابراین همان طور که برای یادگیری برنامه‌نویسی لازم است از قواعد دستوری (Syntax) و معناشناسی (Semantics) آن زبان پیروی کنید، برای شیدرنویسی هم باید همین روال را طی کنید.

تفاوت شیدر و متریال در چیست؟

شیدر یک کد است که رفتار نورپردازی و ویژگی‌های رندر آبجکت و یا افکت‌های دوربین را توصیف می‌کند. ولی متریال مجموعه مقداردهی برای تنظیمات یک شیدر است. این نکته را هم باید در نظر داشته باشیم که شیدرها اغلب برای کنترل نور و اثرات سایه‌ای استفاده می‌شوند، اما هیچ دلیلی وجود ندارد که توانایی آنها به همین موارد محدود شود.

شاید شما علاقه‌ای به کدنویسی نداشته یا دنبال راه‌های ساده‌تری برای نوشتن شیدر باشید، در این صورت باید این نکته را هم مدنظر قرار داد که شما می‌توانید شیدر را به صورت بصری ایجاد کنید (Visual Programming ). این کار نه تنها آسان‌تر است بلکه دیگر نیاز به نوشتن کدهای طولانی ندارید. ابزارهایی نظیر ShaderForge و Amplify Shader Editor دارای محیطی گرافیکی هستند که شما را قادر می‌سازد تا با استفاده از اتصال یکسری Nodeهای مختلف، شیدر خود را به راحتی ایجاد کنید.

برنامه‌نویسی شیدر چه پیش‌نیازهایی دارد؟

در برنامه‌نویسی شیدر لازم است تا با مفاهیم اولیه‌ی گرافیک کامپیوتری و ریاضی (ماتریس‌ها، نسبت‌های مثلثاتی و…) آشنا باشید تا درک بهتری از اصطلاحات گرافیکی ، توابع و الگوریتم‌های ریاضی داشته باشید.

برای شروع شیدرنویسی در یونیتی بهتر است اول آشنایی اجمالی با زبان‌های شیدرنویسی و زبان شیدرنویسی مورد استفاده در یونیتی را داشته باشید:

تصویر بالا سیر تکامل زبان شیدرنویسی را نشان می‌دهد

آناتومی شیدر

 Unity3D از دو نوع مختلف شیدر پشتیبانی می کند: Surface Shader و Fragment and Shader Vertex. نوع سومی هم به نام شیدرهای تابع ثابت (Fixed Function Shaders) وجود دارد، اما آنها اکنون منسوخ شده و در این سری از پست‌ها پوشش داده نخواهند شد. صرف نظر از این که کدام نوع متناسب با نیازهای شماست، آناتومی یک شیدر برای همه آنها یکسان است:

شما می‌توانید چند بخش SubShader داشته باشید، یکی پس از دیگری. آنها حاوی دستورالعمل‌های واقعی برای GPU هستند. Unity3D سعی خواهد کرد تا آنها را به ترتیب اجرا کرده و تا زمانی آن را پیدا کند که سازگار با کارت گرافیک شما باشد. این در هنگام برنامه‌نویسی برای سیستم‌عامل‌های مختلف مفید است، زیرا شما می‌توانید نسخه‌های مختلف یک شیدر مشابه را در یک فایل متناسب کنید.

Properties

ویژگی‌های (Properties) شیدر شما به نوعی معادل با فیلدهای Public در اسکریپت #C است؛ آنها در Inspector متریال ظاهر شده و به شما این امکان را می‌دهد تا آنها را تغییر بدهید.

بر خلاف آنچه که با یک اسکریپت اتفاق می‌افتد، شما می‌توانید ویژگی‌های متریال را در حالی که بازی در ادیتور در حال اجرا است تغییر دهید و حتی پس از اینکه از بازی خارج شدید، ویژگی‌های متریال به حالت اول بر نمی‌گردد (یعنی مقادیر ویژگی متریال مثل مقادیر اسکریپت نیست که بعد از خارج شدن از بازی به حالت اولش برگردد).

در قطعه کد زیر تعریف همه انواع اساسی را که می توانید در یک شیدر داشته باشید پوشش می دهد:

 

نوع دوبعدی که در خطوط 3-4 استفاده شده، نشان می‌دهد که پارامترها بافت هستند. آنها می‌توانند به سفید، سیاه یا خاکستری روشن مقداردهی اولیه شوند. شما همچنین می‌توانید از Bump برای مقداردهی استفاده کنید تا تکسچر به عنوان نرمال مپ استفاده شود. در این مورد، آن به صورت خودکار به رنگ # 808080 (خاکستری) مقداردهی اولیه می‌شود. بردارها و رنگ‌ها همواره دارای چهار عنصر XYZW و RGBA هستند.

تصویر زیر نشان می‌دهد که چگونه این ویژگی‌ها زمانی که شیدر به یک متریال متصل است در Inspector نمایش داده می‌شود.

متاسفانه تعریف ویژگی‌ها به تنهایی کافی نیست. بخش Properties در واقع توسط Unity3D برای دسترسی از Inspector به متغیرهای پنهان در یک شیدر استفاده می‌شود. این متغیرها هنوز باید در قسمت اصلی شیدر تعریف شوند که در قسمت SubShader موجود است. یعنی هر ویژگی‌ای که تعریف می‌شود باید یک متغیر متناظر هم برای آن تعریف کنیم.

بیشتر بخوانید ...   خلاصه نقد سریال The Last of Us از نگاه منتقدان منتشر شد

نوع مورد استفاده برای بافت Sampler2D است. بردارها Float4 هستند و رنگ‌ها به طور کلی Half4 هستند که از 32 و 16 بیت استفاده می‌کنند.

با این حال، انواع داده لازم نیست: شما هیچ خطایی برای اعلام _MyRange به عنوان half به جای float نخواهید داشت. در حین کار شاید به مواردی نسبتاً گیج‌کننده برخورد کنید؛ به عنوان مثال اگر بتوانید یک ویژگی از نوع Vector را تعریف کنید که به متغیر float2 مرتبط است، دو ارزش اضافی توسط Unity3D نادیده گرفته می‌شود.

دستور رندر

همان طور که قبلا ذکر شد، بخش SubShader حاوی کد اصلی شیدر است که در Cg / HLSL نوشته شده و بسیار شبیه به C است.

به طور خلاصه، بدنه‌ی یک شیدر برای هر پیکسل تصویرتان اجرا می شود. پرفورمنس در اینجا بسیار مهم است. با توجه به معماری GPUها، در تعداد دستورالعمل‌هایی که می‌توانید در یک شیدر انجام دهید محدودیتی وجود دارد. این مورد ممکن است از این تقسیم محاسبات در چند گذر جلوگیری کند، اما این موضوع در این آموزش پوشش نخواهد یافت.

بدنه‌ی شیدر، به طور معمول به گونه‌ی زیر تعریف می‌شود:

 خطوط 8-11 شامل کد اصلی Cg است. بخش توسط دستورالعمل CGPROGRAM و ENDCG اعلام شده است.

 خط 3 قبل از بدنه‌ی واقعی، مفهوم برچسب‌ها (Tags) را معرفی می‌کند. برچسب‌ها یک راه برای گفتن ویژگی‌های خاص شیدری است که آن را می‌نویسیم. به عنوان مثال، برچسب مربوط به ترتیب رندر شدن (Queue) و نحوه رندر کردن آن (RenderType) است.

نکته: RenderType برای Replacement Shaders استفاده می‌شود. به این صورت که شیدر جایگزین این برچسب‌ها را خوانده و سپس از یک شیدر مناسب دیگر استفاده می‌کند. حتی اگر از شیدر‌های جایگزین استفاده نکنید بهتر است که شیدرهای خود را برای استفاده در آینده برچسب دار کنید. لینک

GPU هنگام رندر معمولا آن‌ها را با توجه به فاصله خود از دوربین مرتب می‌کند، به طوری که بیشتر آن‌ها برای اولین بار رسم می‌شوند. این کار برای رندر اشیای جامد هندسی(Solid Geometries)  کافی است اما اغلب اشیای شفاف با شکست مواجه می‌شود.

Background (پس‌زمینه) (1000): مورد استفاده برای پس‌زمینه و skyboxes.
Geometry (هندسه) (2000): برچسب به طور پیش‌فرض مورد استفاده برای بیشتر اجسام جامد.
Transparent (شفاف (3000):( مورد استفاده برای متریال‌هایی که ویژگی شفافیت دارند، مانند شیشه، آتش، پارتیکل‌ها و آب.
Overlay (روکش) (4000): مورد استفاده برای جلوه‌هایی مانند شعله ور شدن لنز، عناصر رابط کاربری گرافیکی و متون.

یونیتی همچنین اجازه می‌دهد تا دستورات مرتبط مانند  Background+2 که ترتیب مقدار 1002 را نشان می دهد را مشخص کنید. از دست دادن ترتیب می‌تواند شرایط تند و زننده‌ای تولید کند که در آن یک شی همیشه رسم شده است. حتی زمانی که آب باید توسط مدل‌های دیگر پوشش داده شود.

 

ZTEST

نکته‌ی مهمی که باید به یاد داشته باشید این است که یک شیء شفاف، لزوما همیشه زودتر از یک شیء هندسی ظاهر نمی‌شود.

 GPU به طور پیش‌فرض، یک تست به نام ZTest را اجرا می‌کند که پیکسل‌های پنهان را از رسم شدن باز می‌دارد. برای کار، آن با استفاده از یک بافر اضافی با همان اندازه صفحه نمایش رندر می کند. هر پیکسل شامل عمق (فاصله از دوربین) از جسم رسم شده در آن پیکسل است.

 

Surface versus vertex and fragment

آخرین بخش که باید پوشش داده شود، کد اصلی شیدر است. قبل از انجام این کار، باید تصمیم بگیریم که از کدام نوع شیدر استفاده کنیم. این بخش نگاهی اجمالی به نوشتن شیدر است.در مقالات بعدی نوشتن انواع شیدر را توضیح می‌دهیم. هرچند توضیحات بیشتر در این مقالات نمی‌گنجد، ولی برای شروع کفایت می‌کند.

 

The Surface Shader

هرگاه متریالی که می‌خواهید شبیه‌سازی کنید به تأثیرات نورپردازی واقعی نیاز داشت ، بهتر است از Surface Shader استفاده کنید.

Surface Shaders  محاسبات چگونگی بازتاب نور را پنهان می‌کرده و اجازه می‌دهد تا ویژگی‌های “بصری” مانند albedo ، normals ، بازتاب و غیره را در یک تابع به نام surf مشخص کنیم. این مقادیر سپس به یک مدل نورپردازی متصل می‌شوند که مقدار RGB نهایی را برای هر پیکسل نشان می‌دهد. همچنین شما می‌توانید مدل نورپردازی خود را بنویسید، اما این فقط برای اثرات بسیار پیشرفته مورد نیاز است.

کد Cg یک surface shader معمولی به گونه‌ی زیر تعریف می‌شود:

خط 5 یک بافت را وارد می‌کند و سپس به عنوان ویژگی Albedo  متریال در خط 12 تعریف می‌شود. شیدر از مدل نورپردازی Lambertian (خط 3) استفاده می‌کند که روشی بسیار معمول برای مدل‌سازی چگونگی بازتاب نور روی یک شی است. شیدرهایی که فقط از ویژگی‌های albedo استفاده می‌کنند معمولا diffuse نامیده می‌شوند.

The Vertex and Fragment Shader

 شیدرهای Vertex and fragment خیلی نزدیک به کاری است که نحوه پردازش گرافیکی مثلث‌ها (triangles) می‌کنند و هیچ مفهوم ساخته شده در مورد چگونگی رفتار نور را ندارد. هندسه مدل شما برای اولین بار از یک تابع به نام vert عبور داده می شود که می‌تواند رأس‌های آن را تغییر دهد. سپس مثلث‌ها به طور جداگانه از طریق تابع دیگری به نام frag عبور داده می‌شود که رنگ RGB نهایی را برای هر پیکسل تعیین می‌کند. این شیدرها برای اثرات دوبعدی، پس پردازش(postprocessing) و جلوه‌های ویژه سه‌بعدی مفیدند که در نظر گرفتن آنها به عنوان Surface Shaders بسیار پیچیده است(چون Surface Shaders مدل‌های نورپردازی از قبل تعریف شده و کارهای طولانی را خلاصه کرده، لذا برای نوشتن شیدری متفاوت نیاز دارید تا از fragment shader استفاده کنید و شیدرتان را از صفر بنویسید).

vertex and fragment shader زیر به سادگی یک شی یکنواخت را قرمز و بدون نور می‌کند.

 خطوط 15-17 خطوط را از فضای محلی بومی خود به حالت دوبعدی نهایی روی صفحه تبدیل می‌کنند.

 یونیتی UNITY_MATRIX_MVP  را برای این تعریف کرده است تا ریاضی پشت آن را پنهان کند. پس از این، خط 22 به هر پیکسل رنگ قرمز می‌دهد. فقط به یاد داشته باشید که بخش Cg در vertex and fragment shaders باید در بخش عبور قرار گیرد (ورتکس و فرگمنت شیدر را باید پاس بدهید، ولی سرفیس شیدر را بدون پاس همان طور در ساب شیدر می‌نویسید).این مورد برای شیدرهای ساده‌ی surface shaders نیست، یعنی با آن یا بدون آن هم کار می‌کند.

نکته: mul(UNITY_MATRIX_MVP, float4(pos, 1.0)) با UnityObjectToClipPos معادل است. (لینک)

نکته: ماتریس مدل، مشاهده و طرح ریزی (Model View Projection) سه ماتریس جداگانه است که مدل را از فضای مختصات محلی (Local Position) جسم به فضای جهان(World Position)، نمایش (View) از فضای جهان به فضای دوربین و طرح ریزی از دوربین به صفحه نمایش را تعیین می‌کند.

Model Space, World Space, View Space

منابع :

Unity 5.x Shaders and Effects Cookbook

thebookofshaders

 https://docs.unity3d.com/Manual/SL-ShadingLanguage.html

https://unity3d.com/learn/tutorials/topics/graphics/gentle-introduction-shaders

https://gamedevelopment.tutsplus.com/tutorials/a-beginners-guide-to-coding-graphics-shaders–cms-23313

https://docs.yoyogames.com/source/dadiospice/002_reference/shaders/index.html

A gentle introduction to shaders in Unity3D

https://en.wikipedia.org/wiki/Shader

مقالات مرتبط

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

بازی و سرگرمی

گیمولوژی | رسانه تحلیلی بازی سازی | شیدرنویسی در یونیتی (بخش اول)

در مقاله‌ی قبلی توضیحاتی درباره‌ی شیدر و عملکرد GPU و CPU و انواع شیدر را به صورت اجمالی بررسی کردیم.در این مقاله سعی داریم کمی بیشتر وارد جزئیات شویم تا درک بیشتری از لزوم استفاده‌ی شیدر داشته باشیم.

انواع شیدر:

2D Shaders

شیدرهای دوبعدی روی تصاویر عمل می‌کنند و در گرافیک کامپیوتری «تکسچر» (Texture) نیز نامیده می‌شوند. آنها ویژگی‌های پیکسل را تغییر می‌دهند. در حال حاضر تنها شیدر دوبعدی، شیدرهای پیکسلی هستند. 

Pixel Shaders

شما حتماً تجربه نقاشی با کامپیوتر را دارید و می‌دانید که در این فرایند شما یک دایره، یک مستطیل، یک خط، مثلث و یا هر شکلی را  که تجسم کنید می‌توانید ترسیم کنید. این فرایند بسیار شبیه به نوشتن یک نامه یا یک کتاب دستی است که شامل مجموعه دستورالعمل‌هایی است که یک کار را بعد از دیگری انجام می‌دهند.

شیدرها مجموعه‌ای از دستورالعمل‌ها هستند و باید توجه داشته باشید که دستورالعمل‌ها برای هر پیکسل صفحه نمایش تنها یک بار مجاز است.این بدین معنی است که کدی که نوشته‌اید، بسته به موقعیت پیکسل بر روی صفحه نمایش باید به طور متفاوتی رفتار کند؛ مانند قالب پرسی متون که در گذشته استفاده می‌شد. برنامه شما کاری را به عنوان یک تابع که یک موقعیت را دریافت کرده و یک رنگ را بر می‌گرداند کار می‌کند و وقتی آن را کامپایل می‌کنید این کار فوق‌العاده سریع انجام خواهد شد.

چرا شیدر‌ها سریع هستند؟

برای پاسخ دادن به این سوال، بهتر است شگفتی‌های پردازش موازی را با ذکر یک مثال بررسی کنیم: تصور کنید CPU کامپیوتر شما به عنوان یک لوله صنعتی بزرگ و هر کار به عنوان چیزی است که از آن عبور می‌کند – درست مثل یک Pipe Line.

برخی از وظایف بزرگ‌تر از دیگر وظایف هستند، به این معنی که آن‌ها نیاز به زمان و انرژی بیشتر برای مقابله با آن را دارند. بهتر است بگوییم که آن کار ها نیاز به قدرت پردازش بیشتری دارند.

به دلیل معماری کامپیوترها، هر یک از کارها باید یک بار در یک زمان انجام شود. کامپیوترهای مدرن معمولا دارای گروهی از چهار پردازنده هستند که مانند این لوله‌ها کار می‌کنند. تکمیل وظایف یکی پس از دیگری، برای روان نگه داشتن هر چیزی که در حال اجرا است کاربرد دارد. هر لوله به عنوان یک Thread شناخته شده است. بازی‌های ویدئویی و سایر برنامه‌های گرافیکی نیاز به قدرت پردازش بیش از برنامه‌های دیگر دارند و به دلیل محتوای گرافیکی، آنها باید تعداد زیادی از عملیات Pixel-by-Pixel را انجام دهند. هر پیکسل روی صفحه نمایش باید محاسبه شود و در بازی‌های سه‌بعدی، شکل‌های هندسی و پرسپکتیو نیاز به محاسبه دارند.

بیایید به استعاره لوله‌ها و وظایف‌مان بازگردیم. هر پیکسل روی صفحه‌نمایش نشان‌دهنده‌ی یک کار ساده است. به طور جداگانه هر یک از کارهای پیکسل مسئله ای برای CPU نیست، اما (اینجا مشکل است) کار کوچک باید به هر پیکسل روی صفحه اعمال شود!

این بدان معنی است که در صفحه نمایش 800×600 قدیمی، 480،000 پیکسل باید در هر فریم پردازش شود که به معنی 14،400،000 محاسبات در ثانیه است. بله این مسئله به اندازه‌ای بزرگ است که میکروپروسسور را بیش از حد بارگذاری می‌کند. در یک صفحه نمایش شبکیه 2880×1800 مدرن که در محدوده 60 فریم در ثانیه اجرا می‌شود، محسابات تا 311،040،000 در ثانیه افزایش پیدا می‌کند. مهندسان گرافیک چگونه این مشکل را حل کردند؟

این زمانی است که پردازش موازی یک راه حل خوب است. به جای به هم بستن ریزپردازنده‌های بزرگ و قدرتمند، یا لوله‌ها، بهتر است که تعداد زیادی ریزپردازنده‌ی کوچک موازی در زمان یکسان اجرا شوند. این امکانی است که یک واحد پردازنده گرافیکی (GPU) به ما می‌دهد.

ریزپردازنده‌های کوچک را به عنوان یک جدول از لوله ها و داده‌های هر پیکسل را به عنوان توپ پینگ پنگ در نظر بگیرید.

14،400،000 توپ پینگ پنگ در یک ثانیه تقریبا می‌تواند هر لوله‌ای را مسدود کند. اما یک میز از 800×600 لوله کوچک دریافت 30 موج 480،000 پیکسل در ثانیه را می‌تواند به صورت روان رسیدگی کند. این در رزولوشن‌های بالاتر هم کار می کند. جریان سخت‌افزار موازی شما، می‌تواند بزرگ‌تر باشد.

یکی دیگر از ویژگی‌های فوق العاده قدرتمند GPU، توابع ریاضی خاصی است که از طریق سخت افزار شتاب پیدا می کند. عملیات ریاضی بسیار پیچیده به واسطه‌ی میکروچیپ‌ها به جای استفاده از نرم‌افزار به طور مستقیم حل می‌شود. این بدان معنی است که عملکردهای بی نظیر مثلثاتی و ماتریس سریع‌تر از برق می‌توانند محاسبه شوند.

 Pixel Shaders، که همچنین به عنوان Fragment Shaders شناخته می‌شوند، محاسبه رنگ و ویژگی‌های دیگر هر پیکسل را بر عهده دارند. ساده‌ترین نوع این شیدر، خروجی یک پیکسل صفحه‌نمایش، به عنوان یک رنگ است؛ شیدرهای پیچیده‌تر با چند ورودی/خروجی نیز امکان پذیر است. شیدرهای پیکسلی همیشه از یک رنگ یکسان، برای اعمال مقدار نوردهی، برای انجام Bump Mapping، سایه، برجستگی‌های ظریف، شفافیت و سایر پدیده‌ها استفاده می‌کنند. آن‌ها می‌توانند عمق فرگمنت (برای Z-buffering) یا خروجی بیش از یک رنگ را اگر چندین هدف رندر فعال باشند تغییر دهند. شیدر برای هر راس را Vertex Shader و برای هر پیکسل بافت را Fragment Shader می‌نامند.

به طور کلی حتی رسم یک مثلث دارای بافت (Textured Triangle) نیاز به یک شیدر دارد. در گرافیک سه بعدی، پیکسل شیدر به تنهایی نمی‌تواند جزئیات بسیار پیچیده‌ای اعمال کند، زیرا تنها در یک قطعه واحد (Single Fragment)، بدون اینکه از هندسه صحنه استفاده کند عمل می‌کند. با این حال، شیدرهای پیکسلی دانش هماهنگی صفحه نمایش را دارند و می‌توانند یک تکسچر را دریافت و به شیدر منتقل کنند. این تکنیک می‌تواند طیف گسترده‌ای از اثرات پس پردازش (Postprocessing) دو بعدی، مانند تاری یا تشخیص/تقویت لبه برای سایه‌های کارتونی را فعال کند. Pixel Shaders ممکن است در مراحل متوسط به هر یک از تصاویر دوبعدی یا بافت‌ها در خط لوله اعمال شود، در حالی که Vertex Shaders همیشه به یک صحنه‌ی سه‌بعدی نیاز دارد.

بیشتر بخوانید ...   گیمولوژی | رسانه تحلیلی بازی سازی | پرسش و پاسخ اختصاصی گیمولوژی با پاسکال لوبان (طراح بازی)

3D Shaders

شیدرهای سه بعدی بر روی مدل‌های سه بعدی یا هندسه‌های دیگر عمل می‌کنند اما ممکن است به رنگ‌ها و بافت‌های مورد استفاده برای طراحی مدل یا مش دسترسی پیدا کنند.

Vertex Shader

ورتکس شیدر به طور همزمان روی تک تک ورتکس‌ها کاری انجام می‌دهد. شیدر هیچ آگاهی از رئوس دیگر که شکل گرافیکی اولیه (Graphical Primitive) را تشکیل می‌دهند و هیچ نشانه از اینکه ورتکس متعلق به چه شکل اولیه‌ای (Primitive) بوده ندارد. برای هر راس ورودی، این شیدر خروجی یک راس است.

هر راس دارای مجموعه‌ای از ویژگی‌های ورودی تعریف شده توسط کاربر است. به عنوان مثال: موقعیت، بردار نرمال و مختصات بافت (Texture Position). شیدرهای ورتکس همچنین به متغیرهای یکنواخت دسترسی دارند که به عنوان متغیرهای جهانی (Read-Only Global ) برای تمام رئوس در یک رسم صدا زده می‌شوند.

Geometry Shaders

شیدر‌های هندسی نسبتا نوع جدیدی از شیدر هستند که در Direct3D 10 و OpenGL 3.2 معرفی شدند. قبلا در OpenGL 2.0+ با استفاده از Extensionsها موجود بوده است. این نوع شیدر می‌تواند شکل‌های اولیه‌ی گرافیکی جدیدی مانند نقاط، خطوط و مثلث را از شکل‌های اولیه که به ابتدای خط لوله گرافیکی ارسال می‌شود، تولید کند.

برنامه‌های Geometry Shader پس از Vertex Shaders اجرا می‌شوند. آن‌ها به عنوان ورودی یک شکل اولیه، این امر را با اطلاعات مجاور ممکن می‌سازند. به عنوان مثال، زمانی که در مثلث عمل می‌کند، سه رأس؛ ورودی شیدر هندسی است. پس از آن شیدر می‌تواند صفات اولیه یا بیشتر را که شطرنجی شده‌اند و قطعات آنها (Fragments)، در نهایت به یک Pixel Shader منتقل  می‌شود را منتشر کند.

استفاده های معمول از یک شیدر هندسی شامل موارد زیر است:

 Point Sprite Generation, Geometry Tessellation, Shadow Volume Extrusion and Single Pass Rendering to a Cube Map

Tessellation shaders

همانطور که OpenGL 4.0 و Direct3D 11 به عنوان کلاس جدید شیدر نامیده می‌شوند، یک Tessellation Shader اضافه شده است. این دو مرحله جدید، شیدر را به مدل سنتی اضافه می‌کند: شیدرهای کنترل تسلیت (همچنین به عنوان شیدرهای بدنه – Hull Shaders – شناخته می‌شود) و شیدرهای ارزیابی تسلیت (همچنین به عنوان شیدر‌های دامنه – Domain Shaders – شناخته می‌شوند)، که به موجب آن می‌توانند مش‌های ساده‌تر را به مش‌های ظریف‌تر مطابق تابع ریاضی در زمان اجرا تقسیم کنند.

این نوع شیدر اجازه می‌دهد که وقتی اشیاء به دوربین نزدیک می‌شوند جزئیات دقیق‌تر باشد. یعنی پالیگان‌های بیشتر، در حالی که دورترها می‌توانند پالیگان‌های کمتری داشته باشند، اما با کیفیت قابل مقایسه هستند. همچنین می‌تواند پهنای باند شبکه را به طرز چشمگیری کاهش دهد و اجازه می‌دهد که شبکه‌ها در داخل دستگاه‌های شیدر به جای کم کردن نمونه‌هایی بسیار پیچیده از حافظه، یک لحظه تصحیح شوند.

بعضی از الگوریتم‌ها می‌توانند هر نوع نمونه‌ی بارز دلخواه را به نمایش بگذارند، در حالی که دیگران اجازه‌ی “اشاره کردن” در مش برای تعیین رأس‌ها و لبه‌ها مشخصی را دارند.

Primitive Shaders

معماری AMD Vega میکرو برای یک مرحله جدید شیدر/شیدر‌های اولیه اضافه شده است.

Compute Shaders به برنامه‌های گرافیکی محدود نمی‌شود، بلکه از منابع مشابه برای General Purpose GPU) GPGPU) استفاده می‌شود. آن‌ها ممکن است در خطوط گرافیکی مورد استفاده قرار گیرد. به عنوان مثال برای مراحل اضافی در انیمیشن یا الگوریتم‌های روشنایی مانند رندر پیش رونده (Tiled Forward Rendering). برخی از APIهای رندر اجازه می‌دهد که شیدر‌ها را محاسبه کنید تا به آسانی منابع داده‌ها را با خط لوله گرافیکی به اشتراک بگذارید.

هر بازی‌سازی که با انجین یونیتی کار می‌کند، با کمپوننت‌ها آشنا می‌باشد. کمپوننت چارچوبی است که از اجزای بسیار متفاوت تشکیل شده است.

هر شیئی که در بازی است، شامل تعدادی کمپوننت می‌باشد که روی نگاه و رفتارشان تأثیر می‌گذارد.
در حالی که اسکریپت‌ها چگونگی رفتار اشیا را تعیین می‌کنند، رندرها (Renderers) تصمیم می‌گیرند که چگونه آن‌ها را انجام دهند  و چگونه باید بر روی صفحه ظاهر شود. یونیتی دارای چندین رندر، بسته به نوع هدف است که سعی می‌کنیم آن‌ها را تجسم کنیم. هر مدل سه بعدی معمولاً دارای MeshRenderer است.

 هر شی باید تنها یک MeshRenderer داشته باشد اما خود MeshRenderer می‌تواند چندین متریال داشته باشد. به طور کلی هر متریال یک جلد برای یک شیدر است.

 درک تفاوت بین این کمپوننت‌ها برای درک اینکه شیدر‌ها چگونه کار می‌کنند ضروری است.

نمودار زیر به راحتی بیانگر سه نهاد مختلف است که در گردش کار (Workflow) یونیتی نقش اصلی را بازی می‌کند:

مدل‌های سه بعدی اساساً مجموعه‌ای از مختصات سه بعدی به نام رأس هستند. آن‌ها برای ایجاد مثلث‌ها (Triangles) به یکدیگر متصل شده‌اند. هر رأس می‌تواند چندین اطلاعات دیگر مانند رنگ‌، جهت آن به سمت نقطه (نرمال) و برخی از مختصات برای ساخت بافت‌ها بر روی آن (به نام داده‌های UV) را داشته باشد.

مدل‌ها را نمی‌توان بدون متریال مورد استفاده قرار داد. مدل‌ها جلد‌هایی هستند که شامل یک شیدر و یک مقدار برای پراپرتی‌های آن می باشد. از این رو ، متریال‌های متفاوت می‌توانند شیدر یکسانی، که با اطلاعات مختلف مقدار دهی شده است به اشتراک بگذارند.

مقالات مرتبط

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا