Offscreen Rendering: คืออะไร เทคนิค และการประยุกต์ใช้ในแอปพลิเคชัน

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-06-11 เวลาอ่าน: 10 นาที

Offscreen Rendering (การเรนเดอร์นอกหน้าจอ) เป็นเทคนิคการเรนเดอร์ฉาก 3D ไม่ใช่ไปที่หน้าจอ แต่ไปยังบัฟเฟอร์เท็กซ์เจอร์ (FBO — Framebuffer Object) ซึ่งสามารถนำไปใช้เป็นเท็กซ์เจอร์ได้ในภายหลัง ตาม Apple Metal Documentation, 2025 การเรนเดอร์นอกหน้าจอใช้สำหรับสร้างเงา การสะท้อน เอฟเฟกต์หลังการประมวลผล และการประมวลผลกราฟิกเบื้องต้น Offscreen Rendering ช่วยให้สามารถแบ่งฉากที่ซับซ้อนออกเป็นรอบ (passes) ได้โดยไม่สูญเสียคุณภาพ

ประเด็นสำคัญ

  • Offscreen Rendering — การเรนเดอร์ฉากลงในเท็กซ์เจอร์ แทนที่จะเรนเดอร์ไปที่หน้าจอโดยตรง
  • Framebuffer Object (FBO) — กลไกหลักของการเรนเดอร์นอกหน้าจอใน OpenGL ES
  • Multi-pass rendering — การแบ่งภาพสุดท้ายออกเป็นหลายรอบผ่านบัฟเฟอร์นอกหน้าจอ
  • เงาและการสะท้อน — การประยุกต์ใช้ทั่วไปของการเรนเดอร์นอกหน้าจอในกราฟิกมือถือ
  • ประสิทธิภาพ ของการเรนเดอร์นอกหน้าจอต้องการการปรับให้เหมาะสมเนื่องจากรอบ GPU เพิ่มเติม

Offscreen Rendering คืออะไร?

Offscreen Rendering เป็นวิธีการเรนเดอร์เนื้อหากราฟิกลงในบัฟเฟอร์กลางในหน่วยความจำวิดีโอ แทนที่จะเป็น framebuffer หลักที่แสดงบนหน้าจอ ผลลัพธ์ของการเรนเดอร์นอกหน้าจอจะถูกบันทึกลงในเท็กซ์เจอร์หรือ renderbuffer

วัตถุประสงค์หลักของการเรนเดอร์นอกหน้าจอคือ การเรนเดอร์แบบหลายรอบ (multi-pass rendering) ฉากที่ซับซ้อนจะถูกแบ่งออกเป็นหลายรอบ: ขั้นแรกฉากจะถูกเรนเดอร์ลงในเท็กซ์เจอร์ (offscreen) จากนั้นเท็กซ์เจอร์นี้จะถูกใช้เป็นอินพุตสำหรับรอบถัดไป และดำเนินต่อไปจนกว่าจะได้ภาพสุดท้าย วิธีการนี้ช่วยให้สามารถสร้างเอฟเฟกต์ที่เป็นไปไม่ได้ในรอบเดียว

Framebuffer Object (FBO)

กลไกหลักของการเรนเดอร์นอกหน้าจอใน OpenGL ES คือ Framebuffer Object (FBO) FBO เป็นคอนเทนเนอร์ที่สามารถแนบภาพเท็กซ์เจอร์หรือออบเจกต์ renderbuffer ได้ หลังจากผูก FBO แล้ว คำสั่งการเรนเดอร์ที่ตามมาทั้งหมดจะถูกส่งไปยังเท็กซ์เจอร์ที่แนบไว้ แทนที่จะเป็นหน้าจอ

Offscreen Rendering ทำงานอย่างไร?

Offscreen Rendering ถูกนำไปใช้โดยการสร้างออบเจกต์ framebuffer แยกต่างหาก แนบเท็กซ์เจอร์หรือ renderbuffer เข้ากับมัน สลับบริบทการเรนเดอร์ไปยัง FBO นี้ และดำเนินการคำสั่งวาด เมื่อรอบเสร็จสิ้น บริบทจะกลับไปยัง framebuffer หลัก

วงจรทั่วไปของการเรนเดอร์นอกหน้าจอ

กระบวนการประกอบด้วยสามขั้นตอน: การสร้าง FBO และการแนบเท็กซ์เจอร์ — การเรนเดอร์ฉากลงในเท็กซ์เจอร์นอกหน้าจอ — การใช้เท็กซ์เจอร์ผลลัพธ์ในรอบถัดไป GL_COLOR_ATTACHMENT0 กำหนดว่าเท็กซ์เจอร์สีใดที่จะถูกเรนเดอร์

cpp
// การสร้าง 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 Mapping2+สร้างแผนที่เงาจากแหล่งกำเนิดแสง
Reflection Mapping1-2เรนเดอร์การสะท้อนลงใน cube map
Bloom Effect3-5ทำให้บริเวณสว่างของภาพเปล่งประกาย
HDR Rendering2การปรับโทนสีสำหรับภาพ HDR
Depth Prepass1การเติม depth buffer ล่วงหน้า

Render-to-Texture (RTT)

เทคนิคพื้นฐานที่ผลลัพธ์การเรนเดอร์ถูกบันทึกลงในเท็กซ์เจอร์เพื่อใช้ในภายหลัง Render-to-Texture ใช้สำหรับสร้างแผนที่ขนาดเล็ก เท็กซ์เจอร์ของออบเจกต์ไดนามิก และการแสดงภาพล่วงหน้าของวัสดุที่ซับซ้อน

การเรนเดอร์แบบหลายรอบ (Multi-pass)

เอฟเฟกต์ที่ซับซ้อน (HDR, bloom, depth of field) ต้องการหลายรอบตามลำดับ แต่ละรอบจะเรนเดอร์ฉากลงในเท็กซ์เจอร์นอกหน้าจอ ใช้ฟิลเตอร์ และส่งผลลัพธ์ไปยังรอบถัดไป วิธีการนี้ช่วยให้ สะสมเอฟเฟกต์ โดยไม่สูญเสียคุณภาพของภาพสุดท้าย

Shadow Mapping (การทำแผนที่เงา)

Shadow Mapping เป็นตัวอย่างคลาสสิกของการใช้การเรนเดอร์นอกหน้าจอ เงาถูกสร้างขึ้นในสองรอบ: ขั้นแรกฉากจะถูกเรนเดอร์จากมุมมองของแหล่งกำเนิดแสงลงในเท็กซ์เจอร์ความลึก (offscreen) จากนั้นในระหว่างการเรนเดอร์หลัก แต่ละส่วน (fragment) จะถูกเปรียบเทียบกับแผนที่ความลึกนี้เพื่อพิจารณาว่าอยู่ในเงาหรือไม่

กระบวนการสร้างเงา

รอบแรก: กล้องถูกวางไว้ที่ตำแหน่งของแหล่งกำเนิดแสง ฉากจะถูกเรนเดอร์ลงในบัฟเฟอร์นอกหน้าจอ โดยบันทึกเฉพาะความลึกลงในเท็กซ์เจอร์ รอบที่สอง: การเรนเดอร์หลักพร้อมการตรวจสอบแต่ละส่วน — หากความลึกของมันมากกว่าค่าในแผนที่ความลึก ส่วนนั้นจะ ถูกแรเงา

glsl
// 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) และเวลาเพิ่มเติม

ปัจจัยด้านประสิทธิภาพ

  • จำนวนรอบ — แต่ละรอบพิเศษจะเรนเดอร์ทั้งฉาก ทำให้จำนวนจุดยอดและส่วนที่ประมวลผลเพิ่มเป็นสองเท่า
  • ความละเอียดของเท็กซ์เจอร์นอกหน้าจอ — การเลือกความละเอียดสูงเกินไปจะเพิ่มภาระของแบนด์วิดท์หน่วยความจำ
  • การสลับ FBO — การเปลี่ยนออบเจกต์ framebuffer บ่อยครั้งทำให้เกิดไปป์ไลน์หยุดชะงักและลดการใช้งาน GPU

การปรับประสิทธิภาพการเรนเดอร์นอกหน้าจอ

สำหรับอุปกรณ์มือถือ แนะนำให้: ใช้ renderbuffer แทนเท็กซ์เจอร์หากไม่จำเป็นต้องอ่านผลลัพธ์ (เฉพาะรอบความลึก); เลือกความละเอียดขั้นต่ำที่จำเป็นสำหรับเท็กซ์เจอร์นอกหน้าจอ; รวมรอบเมื่อเป็นไปได้ผ่าน MRT (Multiple Render Targets)

ตัวอย่างโค้ด Offscreen Rendering

Offscreen Rendering บนแพลตฟอร์มต่าง ๆ ถูกนำไปใช้ผ่าน API ของตนเอง มาดูตัวอย่างสำหรับ OpenGL ES และ Apple Metal

ตัวอย่าง OpenGL ES 3.0: การเรนเดอร์ลงเท็กซ์เจอร์

cpp
// การตั้งค่า 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);
// สลับกลับไปยัง framebuffer เริ่มต้น
glBindFramebuffer(GL_FRAMEBUFFER, 0);

ตัวอย่าง Metal (iOS)

cpp
// 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 ในคำง่าย ๆ คืออะไร?

Offscreen Rendering คือเมื่อกราฟิกถูกวาดไม่ใช่บนหน้าจอ แต่ลงในบัฟเฟอร์ที่มองไม่เห็น (เท็กซ์เจอร์) บัฟเฟอร์นี้จะถูกใช้เป็นเท็กซ์เจอร์สำหรับเอฟเฟกต์อื่น ๆ ลองนึกภาพว่าคุณกำลัง วาดบนแผ่นฟิล์มใส ที่คุณวางซ้อนบนภาพสุดท้าย

ทำไมต้องใช้การเรนเดอร์นอกหน้าจอ?

การเรนเดอร์นอกหน้าจอช่วยให้สามารถสร้างเอฟเฟกต์ที่เป็นไปไม่ได้ในรอบเดียว: เงา (การเรนเดอร์จากมุมมองของแสง) การสะท้อน การเบลอ การเรืองแสง (bloom) และการปรับโทนสี HDR แต่ละเอฟเฟกต์ต้องการรอบแยกต่างหากไปยังเท็กซ์เจอร์นอกหน้าจอ

Offscreen Rendering ทำให้ประสิทธิภาพช้าลงหรือไม่?

ใช่ แต่ละรอบนอกหน้าจอจะเพิ่มปริมาณงานของ GPU เป็นสองเท่า เนื่องจากฉากถูกเรนเดอร์อีกครั้ง การปรับให้เหมาะสม รวมถึงการลดความละเอียดของเท็กซ์เจอร์นอกหน้าจอ การใช้ renderbuffer และการรวมรอบผ่าน MRT (Multiple Render Targets)

ความแตกต่างระหว่าง FBO และ Renderbuffer คืออะไร?

FBO (Framebuffer Object) เป็นคอนเทนเนอร์ที่แนบเท็กซ์เจอร์หรือ renderbuffer Texture อนุญาตให้อ่านผลลัพธ์การเรนเดอร์ (จำเป็นสำหรับ shadow mapping, เอฟเฟกต์หลังการประมวลผล) Renderbuffer เร็วกว่า แต่ไม่สามารถใช้เนื้อหาเป็นเท็กซ์เจอร์ได้

API ใดบ้างที่รองรับ Offscreen Rendering?

API กราฟิกสมัยใหม่ทั้งหมด: OpenGL ES (ผ่าน FBO), Apple Metal (ผ่าน MTLRenderPassDescriptor), Vulkan (ผ่าน VkFramebuffer), Direct3D (ผ่าน Render Target View) ตามแนวคิดแล้วกลไกเหมือนกัน — การเรนเดอร์ลงในเท็กซ์เจอร์แทนที่จะเป็นหน้าจอ

สรุป

  • Offscreen Rendering — การเรนเดอร์ฉากกราฟิกลงในเท็กซ์เจอร์ แทนที่จะเรนเดอร์ไปที่หน้าจอโดยตรง
  • Framebuffer Object (FBO) — กลไกหลักของการเรนเดอร์นอกหน้าจอใน OpenGL ES
  • Shadow mapping และการสะท้อน — ตัวอย่างคลาสสิกของการประยุกต์ใช้การเรนเดอร์นอกหน้าจอ
  • Multi-pass rendering ช่วยให้สร้างเอฟเฟกต์ที่ซับซ้อนผ่านรอบตามลำดับ
  • แต่ละรอบ เพิ่มภาระการคำนวณบน GPU เป็นสองเท่า ซึ่งต้องการการปรับให้เหมาะสมอย่างระมัดระวัง
  • Renderbuffer ดีกว่าเท็กซ์เจอร์หากไม่จำเป็นต้องอ่านผลลัพธ์เป็นเท็กซ์เจอร์
  • MRT (Multiple Render Targets) ช่วยให้รวมหลายรอบเป็นหนึ่งเดียว

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม