آشنایی با شیدر و متریال
آشنایی با شیدر و متریال یکی از اصطلاحاتی که همه ما هر روز در پروژه هامون با آنها سرو کار داریم و هر روز از آنها استفاده میکنیم کلمات Shader و Material هستند.
با توجه به رابطه تنگاتنگی که این دو با هم دارن خیلی از دوستان بی آنکه بدانند این کلمات رو به جای یکدیگر استفاده میکنند و یا فکر میکنند هر دو یکی هست و فقط ممکنه در هر نرم افزار یکی از آنها رو استفاده کنند. در صورتی که ایندو اگر چه در یک بخش مورد استفاده قرار میگیرند ولی با هم متفاوت هستند و مقایسه کردن آنها با هم دقیقا شبیه این میمونه که بخواهیم مثلا تکسچر رو با متریال مقایسه کنیم و یا به جای هم استفاده کنیم.
متاسفانه در منابع انگلیسی هم خیلی کم راجب تفاوت ایندو صحبت میشه مگر مقالات تخصصی برنامه نویسی که از نگاه برنامه نویسی رندر تازه تفاوت اصلی ایندو و طرز کارشون مشخص میشه. حتی در تعاریفی هم که از این دو در نرم افزار های مختلف بکار برده میشه تفاوت هایی دیده میشه .
در این مقاله قصد دارم تا یک تعریف دقیق و عمومی خدمتتون ارایه و در کنار آن اشاره ای هم به کاربرد های آنها داشته باشم. با سافت ساز همراه باشید.
تعریف Shader :
شیدر به یک برنامه (کد) نسبتا کوچک گفته میشود که در مرحله رندر قبل از اینکه اطلاعات پروژه مانند مدلها رندر شوند اون برنامه اجرا شده و تغییراتی رو در روی پروژه و اطلاعات اعمال میکند و بعد پروژه رندر میشود.
این تغییرات میتونه در قالب تغییرات روی رنگ باشد مانند محاسبه اثر نور روی سطح آبجکت ها یا میتونه تغییرات روی خود geometry باشه مانند جابه جا کردن ورتکس ها یا اضافه کردن ورتکس های جدید که Displacement یکی از مثال های این نوع تغییرات است.
ولی گسترده ترین کاربرد شیدر همان مورد اول هست که مشخص میکنه نور بعد از برخورد با سطح یک مدل چه اتفاقاتی رو باید سبب شود و چه رنگی باید روی سطح مدل اعمال شود. بنابراین محاسبه Diffuse و Specular و Refraction و SSS و نظایر اینها همه یکی از کاربرد های شیدر میباشد.
انواع شیدر از لحاظ پردازش :
اصولا شیدر روی هر چیزی قابل اجرا شدن هست. مثلا یک برنامه شیدر میتواند به ازای هر یک از پیکسل های تصویر اجرا شود یا میتواند به ازای هریک از ورتکس های مدل اجرا شود یا به ازای هریک از فیس ها یا primitive های مدل یا یک شیدر به ازای یک آبجکت کامل
اما مهمترین دسته بندی های شیدر از لحاظ پردازش به این صورت هستند :
Pixel Shader – Vertex Shader – Fragment Shader – Geometry Shader
بسته به اینکه در کجا اجرا میشود کاربردها و محدودیت های خاص خودش رو داره. مثلا در حالتی که به Pixel Shader معروف است چون برنامه شیدر به ازای تک تک پیکسل ها اجرا میشود بنابراین کمی سرعت پردازش کم میشود ولی در مقابل جزییات خیلی بیشتری رو میتواند نمایش دهد چون محدود به تعداد ورتکس ها نیست.(مثلا در ابعاد 1920*1080 حداقل 2073600 بار اون کد شیدر اجرا میشود !)
بنابراین با توجه به کاری که قراره شیدر انجام بده مشخص میکنیم که کجا باید اجرا شود. مثلا اگر قرار باشه Specular محاسبه شود طبیعتا بهتر است روی پیکسل ها محاسبه شود تا vertex ها.
به این دلیل که اگر روی vertex ها محاسبه شود تعداد ورتکس ها روی نتیجه specular تاثیر میزارد و مثلا اگر یک مربع داشته باشیم که تنها از 4 ورتکس تشکیل شده باشد specular اصلا به درستی روی اون نمی افتاد
اما برعکس اگر قراره شیدری بنویسیم که مثلا ورتکس های مدل رو قراره جابجا بکند نیاز است که اون رو بر ازای ورتکس ها اجرا کنیم (Vertex Shader) چون فقط قراره موقعیت تک تک ورتکس ها رو تغییر دهد. محاسبه Skin و تاثییر گرفتن مدل از Bone یا Joint روی کاراکتر یکی از کاربرد های این نوع شیدر در گیم انجین ها میباشد.
در برخی نرم افزارها مانند Houdini امکان استفاده از شیدر در همه حالاتی که گفتم وجود دارد ولی در برخی دیگر از برنامه ها به خصوص Maya تنها از شیدر در حالتی محدود استفاده میشود و آن هم معمولا پش پرده توسط خود نرم افزار محاسبه میشود و نه توسط کاربر.
همچنین یک برنامه شیدر همیشه قرار نیست تنها اطلاعات مدلهای سه بعدی رو تغییر دهد بلکه میتواند برای تغییر رنگ و سایر اطلاعات یک تصویر دوبعدی هم استفاده شوند که انواع فیلترها و افکت هایی که ما در نرم افزارهای کامپوزیت یا نرم افزارهای اصلاح عکس مانند فوتوشاپ استفاده میکنیم از این دسته هستند. فیلترهایی مانند Blur و Bloom و Glow و غیره همگی فیلتر هایی هستند که با Shader Programming نوشته میشوند و عموما بر روی پیکسلها اجرا میشوند و کلا افکت های Post Process که در گیم انجین ها هم استفاده میشوند در همین دسته جای میگیرند.
تصویر زیر یک مثال از کاربردهای شیدر برای ساخت فیلتر میباشد که همانطور که میبینید عکس واقعی رو طوری تغییر میدهد که حالت کارتونی بگیرد.
با چه زبانی برنامه شیدر را مینویسند ؟
بسته به اینکه در کدام نرم افزار یا کدام موتور رندر میخواهیم شیدر بنویسیم زبان شیدر نویسی خود را میتوانیم انتخاب کنیم. معروفتری زبانهای شیدر نویسی به ترتیب زیر هستند :
RSL یا Renderman Shading Language : یک زبان شیدر نویسی نسبتا عمومی میباشد و برخی موتور رندر ها مانند Arnold یا Cycles آن را ساپورت میکنند. VEX که زبان شیدر نویسی مخصوص نرم افزار هودینی است و زبانهای HLSL , GLSL و CG و غیره که در موتورهای رندر گیم انجین ها کاربرد دارند. البته زبانهای دیگری هم به جز این لیست وجود دارد که من برخی از مهمترین ها رو نوشتم.
در زیر برنامه یک شیدر بسیار ساده به زبان RSL رو مشاهده میفرمایید که یک رنگ ثابت و یک دست رو به کل سطح مدل اعمال میکند.
surface
constant_test1(float Kfb = 1)
{
color surfcolor = color(0.3, 0.9, 0.5);
Oi = Os;
Ci = Oi * Cs * surfcolor * Kfb;
}
همانطور که در تصویر بالا میبینید این شیدر کاری به منبع نور ندارد و یکدست فقط زنگ سبز را روی مدل اعمال میکند.این معادل Surface Shader در نرم افزار مایا میباشد یا کارکردی مشابه پارامتر Emission در متریالها دارد.
اما اگر بخواهیم کاری کنیم که منبع نور روی رنگ سطح هم تاثیر بگذارد باید از توابع مخصوص آن در زبان شیدر استفاده کنیم.به عنوان مثل تابع diffuse در زبان RSL که رنگ سطح بر اساس منبع نور رو مشخص میکند.
در مثال زیر کدهای یک شیدر دیگر رو مشاهده میکنید که علاوه بر محاسبه diffuse این امکان را هم فراهم میکند تا به سطوح داخل و خارج مدل دو رنگ مختلف رو اعمال کنیم.
surface
outsideRed(float Kd = 1;
color inside = color(0,1,0);
color outside = color(1,0,0))
{
color surfcolor = outside;
normal n = normalize(N);
normal nf = faceforward(n, I);
color diffusecolor = Kd * diffuse(nf);
// Here is the “if-the-normal-has-been-flipped technique”
if(nf != n)
surfcolor = inside;
Oi = Os;
Ci = Oi * Cs * surfcolor * diffusecolor;
}
متریال چیست ؟ (Material)
خوب تا الان فهمیدید که شیدر چیست و چه کاری رو میتواند انجام دهد. مثلا محاسبات Diffuse و Specular و … یکی از کاربردهای آن بود.اما در نرم افزارهای سه بعدی برای اینکه بتونیم از شیدر ها برای رندر استفاده کنیم و آن را به یک مدل اعمال کنیم مستقیما نمیتوانیم شیدر رو استفاده کنیم و احتیاج به یک چیز دیگر به اسم متریال داریم !
در حقیقت متریال شبیه به یک پک یا Asset یا یک مجموعه است که در داخل آن از چندین شیدر مختلف تشکیل شده و مجموع آن شیدر ها با هم یک متریال کامل رو میسازند و ما این متریال رو به مدلها اعمال میکنیم.
در تصویر زیر میتونید این ساختار رو مشاهده کنید.
همانطور که در تصویر بالا مشخص است هر مدل از یک متریال که به آن اعمال شده است برخوردار است و اون متریال خود از شیدری که براش نوشته شده است استفاده میکند.
در حقیقت شیدر خود مستقیما روی مدل استفاده نمیشه و با کمک متریال به صورت غیر مستقیم اعمال و استفاده میشود.اما یک متریال همیشه قرار نیست از یک شیدر استفاده کند و ممکن است چندین شیدر در آن متریال استفاده شوند.
اجازه بدید مثالی بزنم.مثلا فرض کنید متریالی لازم داریم که بتواند Diffuse و Specular و Refraction و SSS و همچنین Displacement رو محاسبه کند.
برای ساخت ان احتمالا بیشتر از یک شیدر نیاز است.برای همین میان یکسری شیدر مینویسن که مثلا Diffuse و Specular و Refraction و SSS رو محاسبه کنه و یک شیدر هم برای Displacement و سپس آنها رو با هم پک یا Asset میکنند و سپس آن رو به مدل اعمال میکنند. کلیه پارامترهای مهم که در فرمولهای داخل شیدر تاثیر گذار هستند هم از شیدر میکشن بیرون و در متریال در اختیار کاربر قرار میدهند. مانند تنظیمات مربوط به IOR یا Displacement Scale یا Diffuse Color و غیره.
در برخی نرم افزارها امکان ساخت شیدر نه تنها با نوشتن کد بلکه با محیط ند بیس نیز وجود دارد که سرعت انجام کار رو بسیار بالا میبرد.
در تصویر زیر یک متریال در بلندر رو مشاهده میکنید که از یک شیدر ساخته شده است.(ند سمت چپ)
همانطور که میبینید در این متریال میتوان از شیدر های دیگری برای کنترل Volume و Displacement هم میتوان استفاده کرد (ند سمت راست).
و حالا خود شیدر این متریال (PBR Dielectric) خود از چندین ند کوچکتر ساخته شده که هریک وظیفه پردازش بخشی خاص از شیدر رو بر عهده دارن. مانند Diffuse و Reflection که باز داخل هریک میتونه ندهای دیگری وجود داشته باشه که اون ندها درحقیقت همان کدهای برنامه نویسی به زبان شیدر هستند که اون شیدر اصلی رو میسازند.در مثال زیر که ندهای داخلی شیدر PBR Dielectric رو نمایش میده ند Diffuse در حقیقت معادل تابع diffuse میباشد که در همه زبانهای شیدر نویسی وجود دارد.
ولی ند Reflection خودش از چندین ند دیگر که تشکیل شده است.
و در تصویر زیر هم میتوانید ندها (در حقیقت کدها) یی رو ببنید که Reflection رو محاسبه میکنند.
و البته ندهایی که بخش Fresnel رو محاسبه میکنند ! ?(تصویر زیر)
این سیستم کاملا ند بیس برای ساخت شیدر همانطور که در تصویر بالا میبینید از نوع نوشتاری کدها بسیار مفهموتر و راحتتر میباشد.
البته لازم به ذکر است که در همه نرم افزارها این امکان وجود ندارد که بتونید مستقیما با این سیستم ند بیس شیدر نویسی کنید.به عنوان مثال در نرم افزار مایا شما تنها شیدر ها رو به صورت ند میبینید و میتوانید آنها رو به یکدیگر یا به متریال وصل کنید تا یک متریال کامل بسازید.
ولی خود شیدر ها به صورت یک ند کامل هستند و امکان اینکه در داخل آنها بتوانیم وارد شویم و تغییرات اعمال کنیم وجود ندارد.
یکی از معروفترین و کاملترین نرم افزارهایی که از این لحاظ یعنی از لحاظ شیدر نویسی بسیار قدرتمند و کامل است نرم افزار Houdini میباشد که در داخل آن میتوانید با انواع زبانهای شیدر نویسی مانند RSL برای رندرمن یا VEX که زبان مخصوص هودینی است انواع بسیار پیچیده تری از شیدر ها رو بسازید و استفاده کنید.
امکان استفاده از یک شیدر در چندین متریال (Instancing)
یکی از نکات مهم در بحث رندر این است که وقتی یک شیدر عمومی مینویسید میتوانید از آن شیدر همزمان در چندین متریال مختلف استفاده کنید و این باعث سبکتر شدن برنامه میشود. چون نیازی نیست که یک کد یکسان چندین بار کپی شود. از طرف دیگه امکان اصلاح و تغییر رو راحتتر میکند.
فرض کنید که شیدری نوشتید که فعلا فقط diffuse رو محاسبه میکنه. بعد ده تا متریال در پروژه به مدلها اعمال کردید که همه آنها دارن از این شیدر استفاده میکنند. حالا اگر بخواهید Specular هم توسط دستورات Shader که نوشتید پردازش شود دیگر قرار نیست برید سراغ ده تا شیدر و کدهای آنها هم تغییر بدید.فقط کافیه کدهای شیدر اصلی رو تغییر دهید و اون 10 متریال چون از همون شیدر دارن استفاده میکنند پس نتیجه تغییرات همزمان روی هر 10 متریال اعمال میشود.
مثال دیگر این است که فرض کنید دوتا متریال قراره داشته باشید که هر دو کاملا شبیه هم هستند و قراره Diffuse رو محاسبه کنه.
فقط میخواهید کاری کنید که این متریالها از دوتا تکسچر مجزا استفاده کنند.اگر بخواهید میتوانید مستقیما در داخل خود کدهای شیدر تکسچرها رو بخونید و به رنگ Diffuse بدید.اما با اینکار ما نیاز داریم دوتا شیدر بنویسیم. چون هریک از آنها باید تکسچر متفاوتی رو استفاده کنند.
اما میتونیم این شیدر رو به صورت عمومی بنویسیم و سپس دوتا متریال بسازیم که هر دو از این شیدر به عنوان هسته اصلی دارن استفاده میکنند.ولی در هریک از متریال ها یک تکسچرمتفاوت رو استفاده کنیم تا به Diffuse Color داده بشه. در این حالت شما دوتا متریال با تکسچرهای متفاوت دارید ولی هر دو تنها از یک Shader استفاده میکنند.
احساس نیاز به شیدر نویسی :
ممکنه سوال پیش بیاد که وقتی در خود نرم افزارها و موتورهای رندر Shader های عمومی و آماده نوشته شده است که ما میتونیم به کمک آن هر متریالی رو در بیاریم پس چه نیازی است که بریم سراغ شیدر نویسی ؟
در جواب باید عرض کنم که تسلط به شیدر نویسی کمک میکنه تا در پروژه اگر نیاز باشد بتونیم تنها شیدری بنویسیم که برای مقصودی خاص ساخته شده. برای همین کنترل بسیار بسیار بیشتری روی جزییات آن داریم و میتونیم نتیجه رو تا جایی که ممکنه به واقعیت نزدیکتر کنیم. بدون شک اگر شما شیدری بنویسید که کارش فقط ساخت جنسیت برف میباشد نتیجه بهتری خواهید گرفت تا ساخت برف با متریال استانداردی که برای ساخت هرچیزی استفاده میشود و پارامترهای زیادی دارن که بیشتر آنها هیچ کاربردی در ساخت جنسیت برف ندارند.
از نگاه برنامه نویسی هم وقتی شیدری مخصوص مصارف خاص بنویسید کمی سرعت رندر بالاتر میرود. چون تنها از کدها و دستوراتی استفاده میکنید که برای ساخت اون جنسیت خاص نیاز است.
به عنوان مثال شاید شما با 50 خط بتونید شیدری بسازید که برف رو رندر کنه.ولی اگر از متریال استاندارد بخواهید برای ساخت اون استفاده کنید خود این متریال 500 خط کد داشته باشه که اصلا کاربردی برای ساخت برف هم ندارن.
نتیجه گیری :
- شیدر ها هسته تشکیل دهنده متریال ها هستند که محاسبات و الگوریتم های نحوه تاثیر نور روی سطح در داخل آنها نوشته شده اند.
- شیدر ها در روی چیزهای مختلف مانند پیکسل , ورتکس ، face یا یک آبجکت کلی اجرا میشوند.
شیدرها تنها برای محاسبات نور پردازی کاربرد ندارن و از انها میتوان برای دستکاری تصاویر دو بعدی یا شکل مدلهای سه بعدی یا اطلاعات Volume هم استفاده کرد.(در برخی زبانها و نرم افزار ها مثل vex در هودینی میتوان برای تغییر اطلاعات دیگر مانند اطلاعات صوتی هم استفاده کرد ) - متریال حکم یک asset یا پک یا جعبه رو بر عهده داره که چندین شیدر در داخل آن میتوان استفاده کرد که جنسیت های پیچیده رو براش ساخت.
- اینکه جنسیت مورد نظر تکسچر داشته باشه یا نداشته باشه هیچ ارتباطی به تفکیک شیدر از متریال نداره و حتی اگر نیاز باشه میتوان در داخل خود کدهای شیدر هم تکسچر استفاده کرد.
- یک شیدر میتواند هم زمان در چندین متریال مورد استفاده قرار گیرد.
در پایان یک نکته رو باید عرض کنم :
اینکه در نرم افزارها ممکن است از تعاریف و یا اسامی متفاوتی برای شیدر و متریال استفاده شود. مثلا در نرم افزار Maya از Shading Group به جای متریال استفاده میشود.
بنابراین از روی یک یا دو نرم افزار نمیتوان به تعریف صحیح شیدر و متریال رسید و دوستانی که علاقه دارند نیاز است در کتابها و مقالات برنامه نویسی و شیدر نویسی دنبال جزییات و تعریف های صحیحتر باشند. البته برخی نرم افزار ها و موتورهای رندر به دلیل اینکه کمی بیشتر به برنامه نویسی و بحث های تکنیکی مربوط به این مقوله نزدیک هستند عموما از تعاریف و اسامی ای استفاده میکنند که در مقالات ، کتابهای فنی و برنامه نویسی نیز از همانها استفاده میشود.
برای همین داکیومنتهای نرم افزار هودینی و همچنین موتور رندر Renderman و البته انجین های بازی سازی منابع مناسب تری برای تحقیق میباشند.
نویسنده : سجاد ربیعی
امتیاز دهی به این مطلب
امتیاز سافت ساز
لطفا به این مطلب امتیاز دهید.