Shader Laboratory
848 subscribers
265 photos
15 videos
59 files
404 links
Shader Laboratory
a channel about shaders in telegram

ID : @smkgames

MyStack : goo.gl/smMuqe 😎👌
Download Telegram
تصویر زیر به خوبی نشان دهنده روند کل deferred shading است.
یک مزیت عمده این رویکرد این است که هر قطعه ای که در G-buff قرار دارد، اطلاعات واقعی فرگمنت است که به عنوان یک پیکسل صفحه نمایش به پایان می رسد، depth test ، این اطلاعات قطعه را به عنوان بیشترین فرگمنت نتیجه می دهد .
همچنین آن با چند معایب همراه است G-buffer نیاز دارد که ما مقدار نسبتا زیاد اطلاعات صحنه را در بافرهای رنگ تکسچر ذخیره کنیم که تمام حافظه را می خورد، به ویژه زمانی که اطلاعات صحنه مثل موقعیت بردار ها به دقت بالایی نیاز دارد.عیب دیگر آن این است که blending را پشتیبانی نمی کند(چون ما فقط اطلاعات بیشترین فرگمنت را داریم) و MSAA دیگر کار نمی کند.چندین راه حل برای این عیب ها وجود دارد که ما در آخر آموزش آن را بررسی می کنیم.
پر کردن G-buffer در پاس geometry بسیار کارآمد است زیرا ما مستقیما اطلاعات شیء مانند موقعیت، رنگ یا عادی را به یک فریم بافر با یک مقدار کوچک یا صفر پردازش اطلاعات ذخیره می کنیم. با استفاده از چندین اهداف رندر (MRT) ما حتی می توانیم همه اینها را در یک پاسورد رندر انجام دهیم.
The G-buffer
جی بافر مجموعه ای از تمام بافت هایی است که برای ذخیره اطلاعات مربوط به نورپردازی مورد استفاده قرار می گیرد. بگذارید در این لحظه به طور خلاصه تمام اطلاعاتی که نیاز داریم تا در یک فرگمنت با رندر پیش فرض به نمایش بگذاریم مرور کنیم:
یک مختصات سه بعدی برای محاسبه ی مقدار موقعیت فرگمنت درون یابی شده (interpolated fragment) که برای lightDir و viewDir استفاده می شود.

یک بردار رنگ RGB diffuse همچنین عنوان albedo شناخته شده است.

یک بردار نرمال سه بعدی برای تعیین شیب سطح.

یک float برای شدت اسپکولار

تمام موقعیت های منبع نور و بردارهای رنگ.

بازیکن یا بردار موقعیت دید(viewer's position)
با استفاده از این متغیرها (در هر فرگمنت) که در اختیار داریم می توانیم نور پردازی (Blinn-) Phong را محاسبه کنیم. موقعیت و رنگ های منبع نور و موقعیت دید بازیکن را می توان با استفاده از متغیرهای یکپارچه(uniform ) پیکربندی کرد، اما متغیرهای دیگر هر کدام از اجزای یک شیء خاص هستند. اگر ما به نحوی بتوانیم داده های دقیق مشابه را به تصویب نور پایانی منتقل کنیم، ما می توانیم همان نورپردازی را محاسبه کنیم، حتی اگر بخش هایی از یک quad دوبعدی را رندر کنیم.
در OpenGL هیچ محدودیتی برای چیزی که ما می توانیم در یک تکسچر ذخیره کنیم وجود ندارد، به طوری که منطقی است که تمام داده های هر فرگمنت را در یک یا چند تکسچر هایی که روی صفحه پر شده با نام G-buffer ذخیره کرده و بعدا در پاس نور پردازی استفاده شود. چون تکسچر های G-buffer اندازه ی یکسانی با quad دوبعدی در پاس نور پردازی خواهد داشت،ما دقیقاً همان اطلاعات قطعه ای که در تنظیمات forward rendering 0داشته ایم، دریافت می کنیم، اما این بار در پاس نور پردازی ؛ یک نقشه بر روی یک نقشه وجود دارد.
در شبه کد زیر کل پروسه کمی شبیه به این خواهد بود:
اطلاعاتی که ما برای ذخیره هر فرگمنت نیاز داریم یک بردار موقعیت ، یک بردار طبیعی، یک بردار رنگ و یک مقدار شدت اسپکولار است. بنابراین در پاس geometry ، ما باید تمام اشیاء صحنه را رندر کنیم و این اجزاء داده را در G-buffer ذخیره کنیم.

برای پاس geometry ، باید یک شیء فریم بافر را مقدار دهی اولیه کنیم ، تا به طور مستقیم gBuffer را فراخوانی کند. gBuffer متشکل از چندین buffer متصل و یک شیء رندر بافرعمق (single depth render buffer object) است. برای موقعیت و تکسچر نرمال، ترجیحا از یک تکسچر با دقت بالا (16 یا 32 بیتی float در هر جزء) و مقادیر albedo و مقادیر specular با یک تکسچرپیش فرض (دقت 8 بیتی در هر جزء) استفاده کنیم.
Forwarded from Kamali
از آنجا که ما از رندر چند هدفه (multiple render targets) استفاده می کنیم، باید به صراحت به OpenGL بگوئیم که کدام buffer های رنگ GBuffer مرتبط است ما می خواهیم با glDrawBuffers رندر کنیم.

همچنین جالب توجه است که در اینجا این است که ما اطلاعات موقعیت و اطلاعات نرمال را در بافت RGB ذخیره می کنیم،همانطور که ما هر 3 مولفه را در اختیار داریم، اما اطلاعات رنگ و اطلاعات اسپکولار را در یک بافت RGBA ترکیب می کنیم؛

این ما را از مجبور بودن برای تعریف یک تکسچر بافر رنگ اضافی بی نیاز می کند و باعث صرفه جویی می شود.چون پایپ لاین deferred shading تان پیچیده تر شده و اطلاعات بیشتری نیاز دارد، شما به سرعت دنبال راه های جدیدی برای ترکیب اطلاعات در تکسچر ها به طور تکی می گردید.

بعد ما باید به G-buffer رندر کنیم. با فرض اینکه هر جسم دارای یک Diffuse ، یک تکسچر نرمال و تکسچر شدت اسپکولار است، می خواهیم چیزی شبیه به شیدر فرگمنت زیر را در G-buffer رندر کنیم:
Forwarded from Kamali
چون ما از رندر چند هدفه(multiple render targets) استفاده می کنیم، layout specifier به OpenGL می گوید که کدام بافر رنگ فریم بافر فعالی است که در حال حاضر برای رندر استفاده می کنیم.


در نظر داشته باشید که با محاسبات نور پردازی بسیار مهم است که تمام متغیرها را در یک فضای مختصات نگه دارید؛ در این مورد ما همه متغیرها را در فضای جهان(world-space) ذخیره و محاسبه می کنیم.

اگر ما اکنون مجبور بودیم یک مجموعه بزرگ از اشیاء را در فریم بافرgBuffer رندر کنیم و محتویات آن را نمایش دهیم بوسیله پراجکت کردن بافر های رنگ آن بر روی چهار نقطه صفحه پر شده، چیزی شبیه به این را می بینیم:
Forwarded from Kamali
سعی کنید تجسم کنید که موقعیت فضای جهان و بردارهای نرمال واقعاً درست است. به عنوان مثال، بردارهای نرمال که به سمت راست می آیند، بیشتر به یک رنگ قرمز تراز می شوند، بردارهای موقعیت هم مشابه آن ازorigin صحنه به سمت راست است. به زودی از محتوای G-buffer راضی می شوید، وقت آن است که به مرحله بعدی بروید: پاس lighting.
The deferred lighting pass
با یک مجموعه بزرگ از داده های فرگمنتی در G-Buffer که در اختیار ما قرار دارد، می توانیم به طور کامل رنگ های نور نهایی صحنه را با تکرار بر هر یک از پیکسل بافت های G-Buffer با استفاده از پیکسل و استفاده از محتوای آنها به عنوان ورودی به الگوریتم های نور محاسبه کنیم. از آنجا که مقادیر بافت G-buffer مقادیر تبدیل شده فرگمنت نهایی را نشان می دهد، ما فقط باید عملیات گران قیمت نورپردازی را یک بار در هر پیکسل یکبار انجام دهیم.