Offscreen Rendering (رندرینگ خارج از صفحه) — روشی است که در آن سحنهٔ 3D بهجای نمایش در صفحه، در یک بافر بافت (FBO — Framebuffer Object) رندر میشود که بعداً میتواند به عنوان بافت استفاده شود. بر اساس Apple Metal Documentation, 2025، offscreen rendering برای ایجاد سایهها، بازتابها، پسافکتها و پردازش اولیه گرافیک استفاده میشود. Offscreen Rendering امکان تقسیم سحنهٔ پیچیده به گذرهای (passes) بدون از دست دادن کیفیت را فراهم میکند.
نکات کلیدی
Offscreen Rendering — روشی است برای رندر محتوای گرافیکی در یک بافر واسطه در حافظه ویدیویی، و نه در بافر کادر اصلی (framebuffer) که به صفحه نمایش داده میشود. نتیجه رندرینگ خارج از صفحه در یک بافت یا renderbuffer ذخیره میشود.
هدف اصلی offscreen rendering — رندرینگ چند گذره (multi-pass rendering) است. سحنهٔ پیچیده به چندین گذر تقسیم میشود: ابتدا سحنه در یک بافت (offscreen) رندر میشود، سپس این بافت به عنوان ورودی برای گذر بعدی استفاده میشود، و همین طور تا دستیابی به تصویر نهایی. چنین رویکردی امکان پیادهسازی افکتهایی را فراهم میکند که در یک گذر قابل تحقق نیستند.
مکانیسم کلیدی رندرینگ خارج از صفحه در OpenGL ES — Framebuffer Object (FBO) است. FBO یک کونتینر است که میتوان تصاویر بافت یا اشیای renderbuffer را به آن متصل کرد. پس از اتصال FBO، تمام دستورات رندر بعدی به جای صفحه به بافت متصل هدایت میشوند.
Offscreen Rendering از طریق ایجاد یک شیئٔ framebuffer جداگانه، اتصال یک بافت یا renderbuffer به آن، تغییر زمینه رندر به این FBO و اجرای دستورات ترسیم اجرا میشود. پس از پایان گذر، زمینه به framebuffer اصلی بازگردانده میشود.
فرآیند شامل سه مرحله است: ایجاد FBO و اتصال بافت — رندر سحنه در بافت offscreen — استفاده از بافت حاصل شده در گذر بعدی. GL_COLOR_ATTACHMENT0 مشخص میکند که رندر به کدام بافت رنگی انجام خواهد شد.
// ایجاد FBO برای رندرینگ خارج از صفحه (OpenGL ES 3.0)
GLuint fbo, offscreenTex;
glGenFramebuffers(1, &fbo);
glGenTextures(1, &offscreenTex);
glBindTexture(GL_TEXTURE_2D, offscreenTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER),
GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
offscreenTex, 0);
Offscreen Rendering برای طیف گستردهای از افکتهای گرافیکی استفاده میشود. هر تکنیک نیازمند یک یا چند گذر خارج از صفحه و پیکربندی مشخص FBO است.
| تکنیک | تعداد گذرها | کاربرد |
|---|---|---|
| Shadow Mapping | 2+ | تولید نقشه سایه از منبع نور |
| Reflection Mapping | 1-2 | رندر بازتابها در نقشه مکعبی |
| Bloom Effect | 3-5 | درخشش بخشهای روشن تصویر |
| HDR Rendering | 2 | تون-مپینگ برای تصاویر HDR |
| Depth Prepass | 1 | پر کردن اولیه بافر عمق |
تکنیک پایهای که در آن نتیجه رندر در یک بافت برای استفاده بعدی ذخیره میشود. Render-to-Texture برای ایجاد نقشههای کوچک، بافتهای اشیای دینامیک و تصویرسازی اولیه مواد پیچیده استفاده میشود.
افکتهای پیچیده (HDR, bloom, depth of field) نیازمند چند گذر پیاپی هستند. هر گذر سحنه را در یک بافت offscreen رندر میکند، فیلتر اعمال میکند و نتیجه را به گذر بعدی منتقل میکند. چنین رویکردی امکان انباشت افکتها را بدون از دست دادن کیفیت تصویر نهایی فراهم میکند.
Shadow Mapping — یک نمونه کلاسیک از استفاده offscreen rendering است. سایه در دو گذر ایجاد میشود: ابتدا سحنه از دیدگاه منبع نور در یک بافت عمق (offscreen) رندر میشود، سپس در رندر اصلی هر فراگمنت با این نقشه عمق مقایسه میشود تا مشخص شود که آیا در سایه قرار دارد.
گذر اول: دوربین در موقعیت منبع نور قرار میگیرد، سحنه در بافر offscreen رندر میشود و تنها عمق (depth) در بافت ذخیره میشود. گذر دوم: رندر اصلی با بررسی هر فراگمنت — اگر عمق آن بیشتر از مقدار در نقشه عمق باشد، فراگمنت سایهدار میشود.
// Fragment Shader برای نقشهبرداری سایه
in vec4 vShadowCoord;
uniform sampler2D uShadowMap;
float calcShadow(vec4 coord) {
vec3 uvw = coord.xyz / coord.w;
float depth = texture(uShadowMap, uvw.xy).r;
return (uvw.z > depth + 0.005) ? 0.3 : 1.0;
}
Offscreen Rendering گذرهای افزایشی GPU اضافه میکند که بار محاسباتی کلی و مصرف انرژی را افزایش میدهد. در توسعه موبایل این بهویژه حیاتی است: هر تغییر FBO نیازمند تنظیف خط لوله (pipeline flush) و زمان افزایشی است.
برای دستگاههای موبایل توصیه میشود: استفاده از renderbuffer به جای بافت در صورتی که خواندن نتیجه نیاز نیست (گذر تنها عمق)؛ انتخاب حداقل وضوح لازم برای بافتهای offscreen؛ ادغام گذرها در جایی که ممکن است از طریق MRT (Multiple Render Targets).
Offscreen Rendering در پلتفرمهای مختلف از طریق API-های خاود پیاده سازی میشود. نمونههایی برای OpenGL ES و Apple Metal را بررسی میکنیم.
// راهاندازی FBO و رندر سحنه به بافت
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glViewport(0, 0, texWidth, texHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(offscreenProgram);
glBindVertexArray(sceneVAO);
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, 0);
// بازگشت به بافر فریم پیشفرض
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Metal: گذر رندر خارج از صفحه به بافت
MTLRenderPassDescriptor passDesc = [MTLRenderPassDescriptor renderPassDescriptor];
passDesc.colorAttachments[0].texture = offscreenTexture;
passDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
passDesc.colorAttachments[0].clearColor =
MTLClearColorMake(0.0, 0.0, 0.0, 0.0);
id<MTLCommandBuffer> cmdBuffer = [commandQueue commandBuffer];
id<MTLRenderCommandEncoder> enc =
[cmdBuffer renderCommandEncoderWithDescriptor:passDesc];
[enc drawIndexedPrimitives:MTLPrimitiveTypeTriangle
indexCount:indexCount
indexType:MTLIndexTypeUInt16
indexBuffer:indexBuffer
indexBufferOffset:0];
[enc endEncoding];
سؤالات متداول
Offscreen Rendering وضعیتی است که گرافیک به جای صفحه نمایش، در یک بافر نامرئی (بافت) نقشه میشود. این بافر سپس به عنوان بافتی برای سایر افکتها استفاده میشود. تصور کنید که روی یک فیلم شفاف نقاشی میکشید که بعداً آن را بر روی تصویر نهایی قرار میدهید.
رندرینگ خارج از صفحه امکان ایجاد افکتهایی را فراهم میکند که در یک گذر قابل تحقق نیستند: سایهها (رندر از دیدگاه نور)، بازتابها، محویتروزنی، درخشش (bloom) و تونکردن HDR. هر افکت نیازمند یک گذر جداگانه در بافت offscreen است.
بله، هر گذر خارج از صفحه مقدار کار GPU را دو برابر میکند، چون سحنه مجدداً رندر میشود. بهینهسازی شامل کاهش وضوح بافتهای offscreen، استفاده از renderbuffer و ادغام گذرها از طریق MRT (هدفهای رندر چندگانه) است.
FBO (Framebuffer Object) یک کونتینر است که بافتها یا renderbuffer به آن متصل میشوند. Texture امکان خواندن نتایج رندر را فراهم میکند (برای نقشه سایه، پسافکتها لازم است). Renderbuffer سریعتر است، اما محتوای آن قابل استفاده به عنوان بافت نیست.
همه APIهای گرافیکی مدرن: OpenGL ES (از طریق FBO)، Apple Metal (از طریق MTLRenderPassDescriptor)، Vulkan (از طریق VkFramebuffer)، Direct3D (از طریق Render Target View). مکانیسم مفهومی یکسان است — رندر به بافت به جای صفحه.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید