ปรับแต่งเกม XNA 2D


56

มันสมเหตุสมผลไหมที่จะใช้ตรรกะเพื่อข้ามการเรนเดอร์วัตถุนอกวิวพอร์ตหรือฉันไม่ควรสนใจมันและปล่อยให้ Framework ทำมัน?

คำตอบ:


79

การเลือกสรรเป็นการเพิ่มประสิทธิภาพ ดังนั้นจึงไม่สมเหตุสมผลที่จะทำเพียงเพื่อประโยชน์ของมัน คุณต้องมีเหตุผล


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

(เมื่อฉันพูดว่า "แล้ว" - จริง ๆ แล้วมันทำทั้งหมดนี้ในท่อขนานอย่างหนาแน่น)

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


ดังนั้นมักจะมีค่าใช้จ่ายเพียงเล็กน้อยหรือไม่มีเลยในการปิดหน้าจอเรขาคณิต

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

ฉันขอแนะนำให้อ่านคำตอบนี้และเด็คสไลด์ที่เชื่อมโยงนี้สำหรับคำอธิบายแบบเจาะลึก

ด้วยเหตุนี้หากคุณใช้การคัดแยก frustum คุณสามารถลดจำนวนแบตช์ที่คุณส่งให้ GPU หากคุณมีชุด จำกัด - สิ่งนี้จะช่วยให้คุณได้รับภายใต้วงเงิน


ตอนนี้ - คำถามของคุณเกี่ยวกับ 2D XNA - สมมุติว่าคุณกำลังใช้SpriteBatchอยู่ มันแตกต่างกันเล็กน้อย

ไม่ผิดที่เรียกว่า "Sprite Batch " สิ่งที่ทำคือการไปรต์ที่คุณวาดและทำดีที่สุดที่จะสามารถที่จะส่งไปรท์เหล่านั้นกับ GPU ในbatches น้อยที่สุดโดย batching พวกเขาร่วมกัน

แต่ SpriteBatch จะถูกบังคับให้เริ่มต้นชุดใหม่หาก:

  • คุณวาดสไปรต์ได้มากกว่าที่จะใส่ลงในชุดเดียว (2048 สไปรต์ใน XNA 4)
  • คุณเปลี่ยนพื้นผิว (นี่คือเหตุผลที่มีตัวเลือกเรียงลำดับตามพื้นผิว)

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

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

อย่างไรก็ตาม - การเพิ่มประสิทธิภาพที่ดีขึ้นในการดำเนินการในกรณีนี้คือการใช้atlases texture (aka: sprite sheets) วิธีนี้ช่วยให้คุณลดจำนวนการสลับพื้นผิวได้ดังนั้นจึงเป็นชุด - โดยไม่คำนึงถึงสิ่งที่อยู่บนหน้าจอหรือปิด (นี่คือเหตุผลหลักที่คุณสามารถระบุสี่เหลี่ยมต้นฉบับสำหรับสไปรต์ของคุณ)


(เช่นเคย: นี่คือคำแนะนำเกี่ยวกับการเพิ่มประสิทธิภาพดังนั้นคุณควรวัดและทำความเข้าใจเกี่ยวกับประสิทธิภาพของเกมของคุณและสิ่งที่ จำกัด คุณกำลังกดปุ่มก่อนที่จะใช้ความพยายามในการเพิ่มประสิทธิภาพ)


5
+1 สำหรับการพูดถึงเกี่ยวกับการไม่เลือกสรรเพียงเพื่อประโยชน์ของมัน แต่เมื่อจำเป็นสำหรับประสิทธิภาพการทำงาน
Marcouiller จะ

12
+1 เพื่อบอกฉันว่าแผ่นสไปรต์มีเหตุผลที่จะมีอยู่จริง ๆ นอกเหนือจากความสะดวกของโปรแกรมเมอร์ / นักออกแบบ
Bill

3
+1 สำหรับคำอธิบายที่ดีฉันเรียนรู้มากมายจากคำตอบของคุณ
Jesse Emond

1
ลิงก์ไปยังไฟล์ PDF "Batch, Batch, Batch" เสีย นี่คือการอัปเดตหนึ่งรายการ: ce.u-sys.org/Veranstaltungen/ …
Marton

13

ตามโพสต์ในฟอรัมที่ MSDN กรอบ XNA ไม่ทำการคัดสรร:

เฟรมเวิร์ก XNA จะไม่ทำการคัดสรรใด ๆ สำหรับคุณ - มันไม่สามารถเพราะมันไม่มีเงื่อนงำที่สิ่งใดจะจบลง การแปลงทั้งหมดทำบน GPU และอาจเป็น shader ที่กำหนดเอง

http://xboxforums.create.msdn.com/forums/p/22763/121897.aspx

โพสต์นี้จะกล่าวต่อไปว่าหากคุณมีวัตถุจำนวนมากในฉากของคุณมันอาจคุ้มค่าที่จะกลิ้งไปมา


6
โดยเฉพาะอย่างยิ่งถ้าคุณมีแผนที่เลื่อน (คุณบอกว่ามันเป็น 2D ดังนั้นนี่อาจเกี่ยวข้องกัน) มันเป็นเรื่องเสียถ้าคุณวาดส่วนใหญ่ที่ไม่ต้องการ มันไม่ได้ยากมากนักและคุณอาจเห็นการปรับปรุงบางอย่าง
Michael Coleman

1

ฉันพัฒนาเครื่องยนต์ voxel terrain engine มาหลายปีแล้วใน XNA ในเฟรมส่วนใหญ่เครื่องยนต์จะแปลงหลายร้อยหลายพันล่าม ในการทำโปรไฟล์ของฉันฉันได้พบว่า frustum และการบดเคี้ยวช่วยทำให้ประสิทธิภาพดีขึ้น

โปรไฟล์ XNA HiDef (ไม่ใช่การเข้าถึง) มีคลาส OcclusionQuery ที่ใช้เพื่อดำเนินการ Occlusion Culling Occlusion Culling ลบ Quads เหล่านั้นออกจากวิวพอร์ตที่ถูกซ่อนจากมุมมองโดย Quads อื่น ๆ

สิ่งอื่นที่คุณควรพิจารณาคือการทำให้ทั้งยุคและเนื้อหาแยกออกจากกัน

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

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