فوروارد رندرینگ استاندارد است،تکنیک رندر بیرون جعبه (out-of-the-box) که بیشتر موتورها استفاده می کند.شما شکل هندسی را برای کارت گرافیک تهیه می کنید،شکل هندسی آن را طرح ریزی ، و آن را به ورتکس ها تقسیم می کند و سپس آنها تبدیل و جدا به فرگمنت یا پیکسل هایی می کند که رفتار نهایی رندر را قبل از اینکه روی صفحه فرستاده شوند بیان می کند.
Shader Laboratory
Forward rendering: Geometry shader to vertex shader to fragment Shader
این روش نسبتا خطی است و هر شکل هندسی یک بار در زمان به از خط لوله عبور می کند تا تصویر نهایی را ایجاد کند.
همانطور که از نامش بر می آید ، در رندر تأخیر دارد یعنی رندرینگ تا زمانی که تمام شکل های هندسی لوله را عبور نکند، انجام نمی شود لذا کمی به تعویق می افتد.در نهایت تصویر نهایی پس از اعمالShading تولید می شود.
حالا، چرا این کار را می کنیم؟
حالا، چرا این کار را می کنیم؟
نور پردازی تأخیر افتاده یک deferred rendering اصلاح شده است که سایز G-buffer
را با استفاده از پاس های بیشتر در Scene کاهش می دهد
را با استفاده از پاس های بیشتر در Scene کاهش می دهد
نورپردازی دلیل اصلی رفتن یک مسیر در مقابل مسیر دیگر است. در یک پایپ لاینforward rendering استاندارد، محاسبات روشنایی باید بر روی هر ورتکس و هر فرگمنت در صحنه قابل رویت، برای هر نور در صحنه اجرا شود.
اگر یک صحنه با 100 شکل هندسی داشته باشید و هر شکل هندسی دارای 1000 ورتکس باشد،حتی ممکن است شما حدود 100000 چند ضلعی داشته باشید (یک تخمین بسیار خشن). کارت های ویدئویی می توانند این را به راحتی اداره کنند. اما زمانی که این چند ضلعی ها به فرگمنت شیدر فرستاده می شوند، در این صورت محاسبات نور گرانقیمت اتفاق می افتد و می تواند سرعت واقعی را کاهش دهد
اگر یک صحنه با 100 شکل هندسی داشته باشید و هر شکل هندسی دارای 1000 ورتکس باشد،حتی ممکن است شما حدود 100000 چند ضلعی داشته باشید (یک تخمین بسیار خشن). کارت های ویدئویی می توانند این را به راحتی اداره کنند. اما زمانی که این چند ضلعی ها به فرگمنت شیدر فرستاده می شوند، در این صورت محاسبات نور گرانقیمت اتفاق می افتد و می تواند سرعت واقعی را کاهش دهد
توسعه دهندگان سعی می کنند تا محاسبات روشنایی را به Vertex shader بسپارند تا بتوانند میزان کارهایی را که فرگمنت شیدر باید انجام دهد را کاهش دهند.
محاسبات گرانقیمت نور باید برای هر قطه قابل مشاهده چند ضلعی ها روی صفحه نمایش اجرا شود، صرفنظر از اینکه آیا آن با هم تداخل دارند یا توسط قسمت های چند ضلعی دیگر پنهان می شوند. اگر صفحه نمایش شما دارای رزولوشن 1024x768 باشد (که به هیچ وجه، رزولوشن بسیار بالا نیست) تقریبا 800،000 پیکسل دارید که باید رندر شوند. شما به راحتی می توانید به یک میلیون عملیات قطعه در هر فریم برسید. همچنین بسیاری از قطعات آن را هرگز به صفحه نمایش نمی برند زیرا آنها با آزمایش عمق(depth testing) حذف شده اند و بنابراین محاسبات روشنایی بر روی آنها نابود شده است.
محاسبات گرانقیمت نور باید برای هر قطه قابل مشاهده چند ضلعی ها روی صفحه نمایش اجرا شود، صرفنظر از اینکه آیا آن با هم تداخل دارند یا توسط قسمت های چند ضلعی دیگر پنهان می شوند. اگر صفحه نمایش شما دارای رزولوشن 1024x768 باشد (که به هیچ وجه، رزولوشن بسیار بالا نیست) تقریبا 800،000 پیکسل دارید که باید رندر شوند. شما به راحتی می توانید به یک میلیون عملیات قطعه در هر فریم برسید. همچنین بسیاری از قطعات آن را هرگز به صفحه نمایش نمی برند زیرا آنها با آزمایش عمق(depth testing) حذف شده اند و بنابراین محاسبات روشنایی بر روی آنها نابود شده است.
اگر شما یک میلیون از این قطعات داشته باشید و ناگهان مجبور خواهید شد دوباره آن صحنه را برای هر نور روشن کنید، شما به (تعداد چراغ ها x 1،000،000) عملیات قطعه در هر فریم پرش می کنید! تصور کنید اگر یک شهر پر از چراغ های خیابانی داشته باشید که هر کدام یک منبع نور نقطه ای هستند ...
فرمول برای برآورد این پیچیدگی رندرینگ می تواند در علامت بزرگ O به عنوان O (num_geometry_fragments * num_lights) نوشته شود. در اینجا می توانید ببینید که پیچیدگی به طور مستقیم با تعداد شکل های هندسی و تعداد چراغ ها ارتباط دارد.
فرگمنت ها (قطعه ها) پیکسل های بالقوه هستند که در صورت تکرار در آزمون عمق، بر روی صفحه ظاهر می شوند.
در حال حاضر، برخی از موتورها این را بهینه می کنند، با بریدن چراغ هایی که دور هستند، ترکیب نور، و یا با استفاده از لایت مپ ها (بسیار محبوب، اما ایستا (استاتیک) است)). اما اگر شما می خواهید تعداد چراغ های پویای زیادی داشته باشید، ما نیاز به یک راه حل بهتر داریم.
فرمول برای برآورد این پیچیدگی رندرینگ می تواند در علامت بزرگ O به عنوان O (num_geometry_fragments * num_lights) نوشته شود. در اینجا می توانید ببینید که پیچیدگی به طور مستقیم با تعداد شکل های هندسی و تعداد چراغ ها ارتباط دارد.
فرگمنت ها (قطعه ها) پیکسل های بالقوه هستند که در صورت تکرار در آزمون عمق، بر روی صفحه ظاهر می شوند.
در حال حاضر، برخی از موتورها این را بهینه می کنند، با بریدن چراغ هایی که دور هستند، ترکیب نور، و یا با استفاده از لایت مپ ها (بسیار محبوب، اما ایستا (استاتیک) است)). اما اگر شما می خواهید تعداد چراغ های پویای زیادی داشته باشید، ما نیاز به یک راه حل بهتر داریم.
Deferred Rendering یک رویکرد بسیار جالب است که تعداد آبجکت ها و به طور کلی تعداد فرگمنت ها را کاهش می دهد و محاسبات روشنایی را بر روی پیکسل ها روی صفحه انجام می دهد و در نتیجه با استفاده از اندازه رزولوشن به جای مجموع تعداد قطعه ها عمل می کند.
پیچیدگی deferred rendering را با علامت O بزرگ نمایش می دهند
O(screen_resolution * num_lights)
شما می بینید که در حال حاضر مهم نیست که شما چه تعداد آبجکت روی صفحه ی نمایش دارید تا تعداد چراغ هایی که استفاده می کنید را تعیین کنند.
پیچیدگی deferred rendering را با علامت O بزرگ نمایش می دهند
O(screen_resolution * num_lights)
شما می بینید که در حال حاضر مهم نیست که شما چه تعداد آبجکت روی صفحه ی نمایش دارید تا تعداد چراغ هایی که استفاده می کنید را تعیین کنند.
هر شکل هندسی رندر می شود، اما بدون light shading به چندین بافر فضا روی صفحه نمایش از رندر چند هدفه(multiple render targets) استفاده می کند.
به طور کلی عمق ، نرمال ها تو بافر های جداگانه ای نوشته شده است. سپس این بافرها برای فراهم آوردن اطلاعات کافی برای هر نور برای روشن کردن پیکسل ترکیب می شوند.
به طور کلی عمق ، نرمال ها تو بافر های جداگانه ای نوشته شده است. سپس این بافرها برای فراهم آوردن اطلاعات کافی برای هر نور برای روشن کردن پیکسل ترکیب می شوند.
با دانستن اینکه پیکسل و بردار نرمال آن چقدر دور است ، می توانیم رنگ آن پیکسل را با نور ترکیب کنیم تا بتوانیم رندر نهایی را تولید کنیم.
کدامیک را انتخاب میکنید؟
پاسخ کوتاه این است که اگر شما از بسیاری از نورهای پویا استفاده می کنید، باید از deferred rendering استفاده کنید. با این حال، برخی از اشکالات قابل توجهی وجود دارد:
این فرآیند نیاز به یک کارت گرافیک با چندین اهداف رندر دارد. کارت های ویدئویی قدیمی این را ندارند، بنابراین بر روی آنها کار نخواهد کرد. این مورد دیگه الان هیچ مشکلی ندارد.
این روش رندرینگ نیاز به پهنای باند بالا دارد. شما بافر های بزرگ ارسال می کنید و کارت های قدیمی نیز ممکن است قادر به انجام این کار نباشند. هیچ راه حلی برای این مشکل وجود ندارد.
کدامیک را انتخاب میکنید؟
پاسخ کوتاه این است که اگر شما از بسیاری از نورهای پویا استفاده می کنید، باید از deferred rendering استفاده کنید. با این حال، برخی از اشکالات قابل توجهی وجود دارد:
این فرآیند نیاز به یک کارت گرافیک با چندین اهداف رندر دارد. کارت های ویدئویی قدیمی این را ندارند، بنابراین بر روی آنها کار نخواهد کرد. این مورد دیگه الان هیچ مشکلی ندارد.
این روش رندرینگ نیاز به پهنای باند بالا دارد. شما بافر های بزرگ ارسال می کنید و کارت های قدیمی نیز ممکن است قادر به انجام این کار نباشند. هیچ راه حلی برای این مشکل وجود ندارد.
شما نمی توانید از اشیای شفاف استفاده کنید. (مگر اینکه deferred rendering را با Forward Rendering ترکیب کنید فقط برای اشیا شفاف و سپس می توانید روی این مسئله کار کنید.
هیچ anti-aliasing وجود ندارد. درسته که بعضی از انجین ها مایلند شما این را باور کنید، اما راه حل هایی برای این مشکل وجود دارد: تشخیص لبه وFXAA.
فقط یک نوع متریال اجازه داده شده است.مگر اینکه از اصلاح deferred rendering که Deferred Lighting است استفاده کنید.
سایه ها هنوز به تعداد چراغ ها وابسته هستند و deferred rendering هیچ چیز در اینجا حل نمی کند.
هیچ anti-aliasing وجود ندارد. درسته که بعضی از انجین ها مایلند شما این را باور کنید، اما راه حل هایی برای این مشکل وجود دارد: تشخیص لبه وFXAA.
فقط یک نوع متریال اجازه داده شده است.مگر اینکه از اصلاح deferred rendering که Deferred Lighting است استفاده کنید.
سایه ها هنوز به تعداد چراغ ها وابسته هستند و deferred rendering هیچ چیز در اینجا حل نمی کند.
اگر شما چراغ های زیادی ندارید و یا می خواهید قادر به اجرای سخت افزار قدیمی باشید، باید با forward rendering باقی بمانید و بسیاری از چراغ ها را لایت مپ های سبک استاتیک جایگزین کنید. نتایج هنوز هم می تواند شگفت انگیز باشد.