เหตุใด Vertex Buffer Objects จึงปรับปรุงประสิทธิภาพ


10

จากความเข้าใจพื้นฐานของฉัน Vertex Buffer Object ทำงานได้ดังนี้ (รหัสหลอก):

โดยปกติถ้าใครอยากพูดให้วาดสี่เหลี่ยมจัตุรัสหนึ่งสามารถออกคำสั่งการวาดเส้น

line (0, 0) -> (1, 0)
line (1, 0) -> (1, 1)
line (1, 1) -> (0, 1)
line (0, 1) -> (0, 0)

การใช้ VBO ถ้าฉันเข้าใจถูกต้องจะโหลดจุดยอดลงใน VBO

define VBO
load (0,0) -> VBO
load (1,0) -> VBO
load (1,1) -> VBO
load (0,1) -> VBO
load (0,0) -> VBO

จากนั้นคุณสามารถออกคำสั่งการวาดหนึ่งคำสั่ง

draw VBO vertices

ในขณะที่ฉันเข้าใจว่า VBOs ทำงานอย่างไรฉันไม่รู้ว่าทำไมพวกเขาจึงปรับปรุงประสิทธิภาพ

พวกเขาปรับปรุงประสิทธิภาพได้อย่างไร

คำตอบ:


11

โดยทั่วไปเมื่อคุณแสดงวัตถุในโหมดทันที - การออกคำสั่งการวาดเส้นเช่นคุณสร้างชุดคำสั่งที่คุณส่งไปยังการ์ดกราฟิกเพื่อวาด หากคุณกำลังวาดข้อมูลจำนวนมากหรือวาดบ่อยคุณอาจเสียเวลามากในการส่งข้อมูลนี้ซ้ำแล้วซ้ำอีก

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

โปรดทราบว่าการใช้วัตถุบัฟเฟอร์จุดสุดยอดไม่ได้ให้การเร่งความเร็วที่สำคัญเสมอไป หากคุณวาดวัตถุเพียงครั้งเดียวต่อเฟรมและคุณเปลี่ยนรูปทรงเรขาคณิตในแต่ละเฟรมคุณจะไม่ได้รับประโยชน์จากการหลีกเลี่ยงการคัดลอกแต่ละเฟรม

ประสบการณ์ส่วนใหญ่ของฉันมาจากการเขียนโปรแกรมโดยใช้กราฟิก API เช่น OpenGL ดังนั้นบางคนที่สับสนกับแบ็กเอนด์ของไดรเวอร์กราฟฟิกอาจให้คำตอบที่ละเอียดกว่านี้ได้ แต่ฉันหวังว่านี่จะทำให้ชัดเจนขึ้น


10

มีสองขั้นตอนที่ทำให้ VBO มีประสิทธิภาพมากกว่าโหมดทันที

  1. โหมดทันที ( glBegin / glEnd , glVertex *ฯลฯ ) หมายความว่าในแต่ละเฟรมคุณช้อนฟีดจุดยอดคุณลักษณะสำหรับแต่ละคุณลักษณะ (ตำแหน่งปกติสี ฯลฯ ) ไปยังไดรเวอร์ซึ่งจะทำการฟอร์แมตใหม่และในที่สุดก็ส่ง แพคเกจทั้งหมดเป็นคำสั่งของ GPU ฟังก์ชั่นจำนวนมากเรียกใช้จุดสุดยอดในแต่ละเฟรม
    (โปรดทราบว่าโหมดทันทีเลิกใช้แล้วตั้งแต่ OpenGL 3.0และถูกลบออกจาก 3.2โดยสิ้นเชิง)

  2. โดยใช้อาร์เรย์จุดสุดยอด (ดูglDrawArrays , glDrawElements , glVertexPointerฯลฯ ) คุณสามารถให้ไดรเวอร์ทั้งหมดพร้อมกันและประหยัดภาระในการจัดรูปแบบจุดยอดใหม่ คุณกำลังแทนที่การเรียกใช้ฟังก์ชั่นหลายรายการต่อจุดสุดยอดเพียงแค่การโทรสำหรับตาข่ายทั้งหมด แต่คุณยังต้องทำอีกครั้งหนึ่งเฟรม

  3. Vertex Buffer Objectหรือ VBO (ดูที่ glGenBuffers , glBindBufferฯลฯ ) ก้าวไปอีกขั้นหนึ่งแล้วเก็บข้อมูลทางด้าน GPU: คุณส่งมันเพียงครั้งเดียวแล้วอ้างอิงจากมือจับ คุณประหยัดแบนด์วิดท์โดยไม่ส่งข้อมูลเดียวกันซ้ำ ๆ กันในแต่ละเฟรม


6

ด้วยการใช้อินเทอร์เฟซโหมดทันที (เช่น OpenGL แบบเก่า glBegin () / glEnd () / glVertex ()) คุณจะสามารถป้อนข้อมูลไปยังไดรเวอร์ได้ครั้งละหนึ่งชิ้น จากนั้นจะต้องนำข้อมูลชิ้นเดียวนั้นทำการฟอร์แมตใหม่และส่งต่อไปยังฮาร์ดแวร์ (ซึ่งปัจจุบันหมายถึงการใส่ลงในบัฟเฟอร์คำสั่ง)

โดยการใช้วัตถุบัฟเฟอร์จุดสุดยอดคุณจะมอบบล็อกข้อมูลขนาดใหญ่ (หวังว่า) ให้กับไดรเวอร์ก่อนที่จะต้องใช้งาน สามารถทำการปรับให้เหมาะสมจำนวนมาก (ฟอร์แมตใหม่วางลงในหน่วยความจำวิดีโอ) รวมถึงไม่ต้องป้อนฟีเจอร์ GPU

ในทางปฏิบัติหากคุณวาดดั้งเดิมเพียงจำนวนเล็กน้อยเท่านั้นมันอาจจะไม่สร้างความแตกต่างมากนักอย่างไรก็ตามถ้าคุณวาดตาข่ายสามเหลี่ยมหลายล้านแล้ว VBOs ในหน่วยความจำวิดีโอเป็นวิธีที่จะไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.