บัฟเฟอร์เวอร์เท็กซ์ขนาดใหญ่เทียบกับการดึงสายหลายครั้ง


14

ฉันเพิ่งเริ่มใช้งาน OpenGL และฉันพยายามจะใช้มันเพื่อสร้างเกม 2D ในเกมนี้ฉันมีตารางหกเหลี่ยมที่ประกอบไปด้วยรูปหกเหลี่ยมสีที่แตกต่างกันมาก ในฐานะโปรแกรมเมอร์มือใหม่ OpenGL ฉันเห็นวิธีวาดตารางนี้สองวิธี:

  1. การใช้จุดสุดยอดบัฟเฟอร์กับข้อมูลสำหรับรูปหกเหลี่ยมเดียวจากนั้นใช้ค่าออฟเซ็ตสม่ำเสมอและวนซ้ำบน CPU เพื่อวาดโปรแกรมเดียวกันหลาย ๆ ครั้งจนกว่าฉันจะมีกริด
  2. การสร้างบัฟเฟอร์จุดสุดยอดที่มีการคำนวณล่วงหน้าขนาดใหญ่มากซึ่งดึงรูปหกเหลี่ยมทั้งหมดในการโทรครั้งเดียว

วิธีใดมีประสิทธิภาพมากที่สุด มีวิธีที่ดีกว่าในการทำเช่นนี้?


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

การส่งผ่านมักจะอ้างถึงสถานการณ์ที่การดำเนินการเรนเดอร์ตัวหนึ่งอาศัยผลลัพธ์ของการดำเนินการก่อนหน้า สิ่งที่คุณถามเกี่ยวกับคำถามนี้เกี่ยวข้องกับการลดจำนวนการโทรออกภายในครั้งเดียว ฉันรู้ว่ามันฟังดูคล่องแคล่ว แต่มันสำคัญมากที่จะต้องเข้าใจความแตกต่างไม่เช่นนั้นอัลกอริธึมแบบมัลติพาสจะไม่สมเหตุสมผลนัก)
Andon M. Coleman

@ AndonM.Coleman อืมขอบคุณฉันไม่คุ้นเคยกับคำศัพท์กราฟิกอย่างชัดเจน ดังนั้นในกรณีนี้ฉันจะอธิบายได้อย่างไร เรียก shader / โปรแกรมหลายรายการ?
Alexis King

คุณสามารถบอกได้ทันทีว่านี่เป็นอัลกอริธึมการส่งผ่านเดียวเนื่องจากไม่มีการพึ่งพาคำสั่งซื้อ คุณสามารถวาดรูปหกเหลี่ยมเหล่านี้ในลำดับใดก็ได้และยังคงได้ผลเหมือนเดิม คุณอาจใช้การเรียกแบบดึงหลายครั้งเพื่อให้ OpenGL กับข้อมูลที่จำเป็นในการแสดงผล แต่ OpenGL นั้นมีอิสระในการวาดทั้งหมดในแบบคู่ขนานได้อย่างมีประสิทธิภาพเนื่องจากไม่มีการพึ่งพา หากเป็นแบบหลายรอบดังนั้นรูปหกเหลี่ยม B อาจต้องการผลลัพธ์ของรูปหกเหลี่ยม A ก่อนที่จะถูกดึงออกมาหรือคุณอาจต้องวาดรูปหกเหลี่ยมเดียวกันหลาย ๆ ครั้งแล้วรวมผลลัพธ์
Andon M. Coleman

คำตอบ:


9

มีสองสามวิธีในการสร้างกริดเช่นนี้

วิธีที่มีประสิทธิภาพมากที่สุดคือการจัดวาง วิธีนี้ทำให้คุณเป็นรูปหกเหลี่ยมเพียงครั้งเดียวใน VBO และแสดงผลเป็นร้อย, พันหรือล้านครั้ง คุณสามารถทำได้ด้วยตนเองโดยใช้เครื่องแต่งกายที่มีชุดเครื่องแบบตามที่คุณพูดในจุดที่ 1 แต่ยังมีฟังก์ชั่น OpenGL ในตัวอีกด้วย เพื่อที่จะดูที่glDrawElementsInstanced

โปรดทราบว่าการอินสแตนซ์นั้นเร็วกว่าวิธีอื่นเท่านั้นหากคุณวาดออบเจ็กต์อินสแตนซ์มากกว่าจำนวนหนึ่ง ตัวอย่างเช่นการวาด 300 สามารถทำได้เร็วขึ้นโดยใช้ 1 VBO ใหญ่ แต่การวาด 2 ล้านสามารถทำได้เร็วขึ้นถ้าคุณใช้การเรนเดอร์แบบอินสแตนซ์

ถ้าคุณใช้การแสดงผล instanced คุณสามารถส่งข้อมูลต่อวัตถุโดยใช้ตัวหารแอตทริบิวต์ ในกรณีของคุณคุณต้องการส่งตำแหน่งและสี

บทแนะนำที่ดีเกี่ยวกับการเรนเดอร์แบบอัตโนมัติ: คลิก

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

นอกจากนี้โปรดทราบว่าการเรนเดอร์แบบอินสแตนซ์เป็นฟังก์ชั่น OpenGL ที่ทันสมัยและคุณจะต้องใช้เฉดสีเพื่อใช้งาน แต่เป็นการดีที่สุดที่จะเรียนรู้วิธีที่ถูกต้องตั้งแต่ต้น


2
อินสแตนซ์ไม่จำเป็นต้องมีประสิทธิภาพมากที่สุด ในการใช้งานหลายอย่างที่ฉันได้เห็นโปรไฟล์ของการสนับสนุน instancing ถูกตรึงบนเพื่อความสอดคล้อง แต่ช้ากว่าการวาดวัตถุจำนวนมากทีละรายการ เป็นตัวเลือกและเป็นสิ่งที่ดี แต่ควรระมัดระวังในการทำโปรไฟล์และทดสอบระบบปฏิบัติการ / ฮาร์ดแวร์เป้าหมายก่อนที่จะทำการตั้งสมมติฐานใด ๆ เกี่ยวกับ "ประสิทธิภาพสูงสุด"
Sean Middleditch

ตกลง ฉันได้เห็นการแสดงที่แตกต่างกันใน Windows / Linux และ Ati / nVidia เป็นต้น ขอบคุณสำหรับการเพิ่ม
Basaa

1
ในความเป็นจริง. หากคุณวาดตาข่ายรวมหลาย ๆ ตัวภายใน vbo เดียว (ที่แบ่งปันพื้นที่เดียวกัน) ไม่มีทางที่เร็วขึ้น ปัญหาของการอินสแตนซ์คือ: จุดยอดไม่ใช่อินสแตนซ์ไขว้จากการคำนวณแบบขนาน มันกำจัด gpu / cpu / gpu sync / drawcall เท่านั้น ดังนั้นจึงเร็วกว่าที่จะวาดบัฟเฟอร์จุดสุดยอดหนึ่งอันที่มี 1,000 ทรงกลมกว่าวาด 1,000 ทรงกลมด้วยการติดตั้งฮาร์ดแวร์ (ไม่มีการคัดออกอย่างเหมาะสม / การเพิ่มประสิทธิภาพรายละเอียดระยะวัตถุที่เกี่ยวข้อง)
Jeroen van Langen

3

วิธีที่ 1 นั้นง่ายกว่าในการเขียนโค้ดและจะใช้ได้ตราบใดที่คุณไม่มีรูปหกเหลี่ยมมากเกินไปในคราวเดียว คุณอาจต้องการที่จะยึดติดกับสิ่งนี้ตั้งแต่คุณยังใหม่กับ OpenGL เพื่อหลีกเลี่ยงการวางความซับซ้อนมากเกินไปในจานของคุณในครั้งเดียว

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

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