VSync (Vertical Synchronization) เป็นเทคโนโลยีที่ซิงค์เอาต์พุตของเฟรมใหม่แต่ละเฟรมจาก GPU กับอัตรารีเฟรชของหน้าจอ ขจัดอาการภาพฉีกขาด ตาม Apple Metal Documentation การซิงค์กับ VBlank เป็นสิ่งจำเป็นสำหรับการเรนเดอร์ที่ราบรื่นบนอุปกรณ์มือถือ ภาพฉีกขาด เกิดขึ้นเมื่อเฟรมถูกอัปเดตระหว่างการกวาดแนวตั้ง และ VSync ป้องกันการผสมนี้
ประเด็นสำคัญ
VSync (Vertical Synchronization) เป็นกลไกฮาร์ดแวร์-ซอฟต์แวร์ที่บังคับให้ GPU รอสัญญาณการบล็อกแนวตั้ง (VBlank) ก่อนที่จะแสดงเฟรมใหม่ หากไม่มี VSync GPU สามารถส่งเฟรมได้ทุกเวลา แม้ว่าหน้าจอกำลังวาดเฟรมปัจจุบันอยู่ ซึ่งทำให้เกิดภาพฉีกขาดตามเส้นแนวนอน
บนอุปกรณ์มือถือ VSync ถูกใช้งานที่ระดับไดรเวอร์กราฟิกและระบบปฏิบัติการ iOS ใช้การซิงค์ VBlank ผ่าน Metal ส่วน Android ใช้ผ่าน SurfaceFlinger และ BufferQueue เมื่อเปิดการซิงค์แนวตั้ง FPS ของแอปพลิเคชันจะไม่เกินอัตรารีเฟรชของหน้าจอ — 60, 90 หรือ 120 Hz ขึ้นอยู่กับรุ่นอุปกรณ์
คำว่า การซิงค์แนวตั้ง มาจากหลักการทำงานของจอภาพ CRT ซึ่งลำแสงอิเล็กตรอนวาดภาพทีละบรรทัดจากบนลงล่าง หลังจากเสร็จสิ้นเฟรม ลำแสงจะกลับไปที่มุมซ้ายบน — ช่วงเวลานี้เรียกว่าการบล็อกแนวตั้ง จอ LCD และ OLED สมัยใหม่ยังคงใช้คำนี้ แม้ว่าจะทำงานทางกายภาพแตกต่างกัน
GPU เรนเดอร์เฟรมใน back buffer ในขณะที่หน้าจออ่านจาก front buffer VSync รับประกันว่าการสลับบัฟเฟอร์เกิดขึ้นเฉพาะในช่วง VBlank — เมื่อหน้าจอแสดงเฟรมปัจจุบันเสร็จและพร้อมสำหรับเฟรมถัดไป กลไกนี้เรียกว่า การบัฟเฟอร์คู่พร้อมการซิงค์ VBlank
การบัฟเฟอร์คู่ ใช้บัฟเฟอร์สองตัว: front buffer ที่แสดงบนหน้าจอ และ back buffer ที่ GPU เขียนเฟรมปัจจุบัน เมื่อเฟรมพร้อม บัฟเฟอร์จะถูกสลับ เมื่อเปิด VSync การสลับนี้จะถูกเลื่อนออกไปจนถึง VBlank ที่ใกล้ที่สุด GPU จะว่างหากเฟรมพร้อมก่อน VBlank ซึ่งลดประสิทธิภาพแต่กำจัดภาพฉีกขาด
// OpenGL — การเปิด VSync ผ่าน WGL_EXT_swap_control
HDC hdc = wglGetCurrentDC();
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT =
reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(
wglGetProcAddress("wglSwapIntervalEXT"));
wglSwapIntervalEXT(1); // 1 = VSync เปิด, 0 = ปิด
VBlank เป็นช่วงสั้นๆ ระหว่างบรรทัดสุดท้ายของเฟรมปัจจุบันและบรรทัดแรกของเฟรมถัดไป ในช่วงเวลานี้ หน้าจอไม่อัปเดตพิกเซล และการสลับบัฟเฟอร์เกิดขึ้นโดยไม่มีสิ่งแปลกปลอม ระยะเวลา VBlank ขึ้นอยู่กับอัตรารีเฟรช: ที่ 60 Hz บนหน้าจอ 1080p VBlank ใช้เวลาประมาณ 1.4 ms หาก GPU ไม่เสร็จสิ้นการเรนเดอร์ก่อน VBlank เฟรมจะถูกข้ามและหน้าจอแสดงเฟรมก่อนหน้าอีกหนึ่งรอบ — ซึ่งรับรู้ได้ว่าเป็นการกระตุก
การบัฟเฟอร์สามชั้น แก้ปัญหา GPU ว่างโดยเพิ่มบัฟเฟอร์ที่สาม GPU สามารถเริ่มเรนเดอร์เฟรมถัดไปได้ทันทีแม้ว่า back buffer ตัวใดตัวหนึ่งกำลังรอ VBlank อยู่ ซึ่งเพิ่ม FPS เมื่อใช้ VSync แต่เพิ่มความหน่วงอีกหนึ่งเฟรม บนอุปกรณ์มือถือ การบัฟเฟอร์สามชั้นถูกใช้ในเอนจินเกมบางตัวและใน Vulkan ผ่านโหมด Mailbox
การปิด VSync ให้ FPS สูงสุดและอินพุตแล็กต่ำสุด แต่แลกกับสิ่งแปลกปลอมทางภาพ สำหรับเกมมือถือและแอปพลิเคชันที่มีแอนิเมชันราบรื่น การเลือกระหว่าง VSync และการปิดมันคือการประนีประนอมระหว่างความคมชัดของภาพและความตอบสนองของการควบคุม
ภาพฉีกขาด คือการแบ่งในแนวนอนที่ส่วนบนของหน้าจอแสดงเฟรมก่อนหน้าและส่วนล่างแสดงเฟรมถัดไปแล้ว สิ่งนี้เกิดขึ้นเมื่อ GPU สลับบัฟเฟอร์ระหว่างการกวาดหน้าจอ บนอุปกรณ์มือถือ ภาพฉีกขาดจะสังเกตเห็นได้ชัดโดยเฉพาะเมื่อเลื่อนเร็วหรือในฉากที่เคลื่อนไหวด้วยอัตราเฟรมสูง จอ OLED ที่ตอบสนองทันทีทำให้ภาพฉีกขาดมีความคมชัดมากกว่าเมื่อเทียบกับ LCD
ความรุนแรงของภาพฉีกขาดขึ้นอยู่กับอัตราส่วนของ FPS ต่ออัตรารีเฟรช ที่ 60 FPS บนหน้าจอ 60 Hz ภาพฉีกขาดปรากฏเป็นเส้นหยุดนิ่งเส้นเดียว ในขณะที่ 300 FPS บน 60 Hz ปรากฏเป็นรอยฉีกขาดเป็นคลื่นหลายจุดเคลื่อนที่จากบนลงล่าง ยิ่ง FPS สูงเมื่อเทียบกับอัตรารีเฟรช ยิ่งมีรอยฉีกขาดมากขึ้นและสังเกตเห็นได้ชัดเจนขึ้น
อินพุตแล็ก เมื่อใช้ VSync คือความหน่วงระหว่างการกดปุ่มและการเห็นผลบนหน้าจอ การซิงค์แนวตั้งเพิ่มความหน่วงเฉลี่ยหนึ่งเฟรม (16.7 ms ที่ 60 Hz) และด้วยการบัฟเฟอร์สามชั้น — สูงสุดสองเฟรม สำหรับแอปพลิเคชันทั่วไป ความหน่วงนี้ไม่สามารถรับรู้ได้ แต่สำหรับเกมยิงปืน เกมต่อสู้ และเกมจังหวะ มันสำคัญมาก: มืออาชีพสังเกตเห็นความหน่วงแม้เพียง 8 ms
จากการวิจัยของ NVIDIA (2024) อินพุตแล็กเฉลี่ยใน CS:GO ที่ 60 FPS โดยไม่มี VSync คือ 22 ms และมี VSync — 39 ms ที่ 144 FPS ความแตกต่างลดลงเหลือ 14 เทียบกับ 18 ms ตามลำดับ บนแพลตฟอร์มมือถือ อินพุตแล็กของ VSync มีความสำคัญน้อยกว่าเนื่องจากอินพุตแบบสัมผัส ซึ่งความหน่วงฮาร์ดแวร์ของหน้าจอสัมผัส (10–30 ms) ปกปิดความหน่วงการซิงค์ที่เพิ่มขึ้น
ในการพัฒนาแอปมือถือ VSync ถูกควบคุมผ่าน API กราฟิก เอนจินเกม และการตั้งค่าระบบปฏิบัติการ iOS ให้การควบคุมน้อยกว่า Android ให้มากกว่าผ่าน Vulkan และ OpenGL ES การเลือกโหมดขึ้นอยู่กับประเภทของแอปพลิเคชัน: เกม, UI หรือวิดีโอ
Unity ใช้การตั้งค่า QualitySettings.vSyncCount: 0 — ปิด, 1 — VSync ทุก VBlank, 2 — ทุก VBlank ที่สอง (FPS ลดลงครึ่งหนึ่ง) ใน Unreal Engine VSync ถูกควบคุมผ่านคำสั่งคอนโซล r.VSync และ DefaultEngine.ini สำหรับบิลด์มือถือ แนะนำให้ปิด VSync ใน Unity และใช้ตัวจำกัด FPS แบบกำหนดเอง เนื่องจาก VSync ในตัวของ Android SurfaceFlinger สามารถสร้างความหน่วงที่ไม่สามารถคาดเดาได้
// Unity — การควบคุม VSync และ FPS
void Awake()
{
// 0 = VSync ปิด, 1 = VSync เปิด
QualitySettings.vSyncCount = 0;
// ตัวจำกัด FPS แบบกำหนดเองแทน VSync
Application.targetFrameRate = 60;
}
Vulkan ให้การควบคุมอย่างสมบูรณ์ผ่าน VkSwapchainPresentInfo และ presentMode: VK_PRESENT_MODE_FIFO_KHR — VSync แบบคลาสสิก, VK_PRESENT_MODE_MAILBOX_KHR — บัฟเฟอร์สามชั้นโดยไม่รอ, VK_PRESENT_MODE_IMMEDIATE_KHR — ไม่มีการซิงค์ Metal ใน iOS ควบคุม VSync ผ่าน CAMetalLayer.displaySyncEnabled เริ่มตั้งแต่ iOS 14 Apple แนะนำให้ใช้ displaySyncEnabled = true เป็นค่าเริ่มต้นสำหรับแอปพลิเคชันทั้งหมดยกเว้นเกมแนวอาร์เคด
| โหมด | คำอธิบาย | ความหน่วง |
|---|---|---|
| FIFO | VSync แบบคลาสสิกพร้อมรอ VBlank | 1 เฟรม |
| Mailbox | บัฟเฟอร์สามชั้น ทิ้งเฟรมเก่า | 1–2 เฟรม |
| Immediate | ไม่มีการซิงค์ FPS สูงสุด | 0 เฟรม |
ตัวจำกัด FPS เป็นทางเลือกแทน VSync ที่แอปพลิเคชันจำกัดอัตราเฟรมโดยทางโปรแกรมโดยไม่รอ VBlank วิธีการนี้ให้ความหน่วงที่คาดเดาได้และไม่ขึ้นอยู่กับอัตรารีเฟรชของหน้าจอ บน Android การจำกัด FPS ถูกใช้งานผ่าน Choreographer บน iOS — ผ่าน CADisplayLink พร้อมควบคุมเวลาส่งออกด้วยตนเอง
VSync แบบดั้งเดิม มีข้อเสียพื้นฐาน: มันผูกติดกับอัตรารีเฟรชคงที่ของหน้าจอ หาก GPU สร้าง 45 FPS บนหน้าจอ 60 Hz VSync ไม่สามารถแสดง 45 เฟรมได้ — มันแสดง 30 (ข้ามทุก VBlank ที่สอง) หรือสลับระหว่าง 60 และ 30 ด้วยช่วงเวลาที่ไม่สม่ำเสมอ สิ่งนี้สร้างการกระตุก ซึ่งทำลายประสบการณ์การเล่นเกมมากกว่าภาพฉีกขาด
การซิงค์แบบปรับตัว (FreeSync, G-Sync, Apple ProMotion) แก้ปัญหานี้โดยเปลี่ยนอัตรารีเฟรชของหน้าจอแบบไดนามิกตาม FPS ของแอปพลิเคชัน หากแอปพลิเคชันสร้าง 47 FPS หน้าจอจะเปลี่ยนเป็น 47 Hz — แต่ละเฟรมจะแสดงเพียงครั้งเดียว โดยไม่มีภาพฉีกขาดหรือกระตุก ProMotion ใน iOS เลือกความถี่จาก 24 ถึง 120 Hz โดยอัตโนมัติ สร้างสมดุลระหว่างความลื่นไหลและการใช้พลังงาน
บนอุปกรณ์มือถือ การซิงค์แบบปรับตัวกำลังกลายเป็นมาตรฐาน: iPad Pro (2017+) พร้อม ProMotion, เรือธง Android พร้อมจอ LTPO (Samsung Galaxy S23 Ultra, Google Pixel 8 Pro) รองรับอัตรารีเฟรชแบบไดนามิกตั้งแต่ 1 ถึง 120 Hz สำหรับนักพัฒนา นี่หมายความว่า VSync ในความหมายดั้งเดิมถูกแทนที่ด้วยการจัดการของระบบ — เพียงแค่ตั้งค่า targetFrameRate และระบบปฏิบัติการจะปรับอัตรารีเฟรชเพื่อสมดุลที่เหมาะสมที่สุดระหว่างความลื่นไหลและอายุการใช้งานแบตเตอรี่
คำถามที่พบบ่อย
ไม่ สำหรับเกมที่เคลื่อนไหวเร็ว (เกมยิงปืน เกมต่อสู้) VSync เพิ่มอินพุตแล็กโดยไม่มีประโยชน์ที่มีนัยสำคัญ — ภาพฉีกขาดบนจอ OLED มือถือสังเกตได้น้อยกว่าเนื่องจากขนาดหน้าจอที่เล็ก สำหรับเกมทั่วไปและ UI VSync ช่วยเพิ่มการรับรู้ถึงความลื่นไหล
VSync ลดการใช้พลังงาน เพราะ GPU ไม่เรนเดอร์เฟรมที่ไม่จำเป็น เมื่อปิด VSync GPU ทำงานที่ความถี่สูงสุด และทุกเฟรมที่ไม่ได้แสดงจะสิ้นเปลืองพลังงานและทำให้อุปกรณ์ร้อนขึ้นโดยไม่มีประโยชน์ต่อผู้ใช้
VSync ซิงค์เอาต์พุตเฟรมกับ VBlank ของหน้าจอ ในขณะที่ตัวจำกัด FPS เพียงจำกัดความถี่การเรนเดอร์ในโค้ดของแอปพลิเคชัน ตัวจำกัด FPS ไม่ได้กำจัดภาพฉีกขาด แต่ให้ความหน่วงที่คาดเดาได้โดยไม่ผูกติดกับอัตรารีเฟรชของหน้าจอ
เมื่อ GPU ไม่เสร็จสิ้นเฟรมก่อน VBlank VBlank จะถูกข้ามและเฟรมจะแสดงเป็นเวลาสองรอบรีเฟรช ที่ 60 Hz จะให้ 30 FPS การบัฟเฟอร์สามชั้นช่วยลดผลกระทบนี้โดยให้ GPU เริ่มเฟรมถัดไปโดยไม่ต้องรอ
ใช่ iOS ProMotion (iPad Pro, iPhone 13 Pro+) รองรับความถี่ไดนามิก 24–120 Hz Android ผ่านจอ LTPO รองรับ 1–120 Hz นักพัฒนาไม่จำเป็นต้องจัดการด้วยตนเอง — ระบบจะเลือกความถี่ที่เหมาะสมที่สุดโดยอัตโนมัติ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม