วิธีที่มีประสิทธิภาพในการแสดงภูมิประเทศขนาดใหญ่ใน XNA


10

ฉันกำลังสร้างเกม XNA ที่ต้องการพื้นที่ขนาดใหญ่สำหรับผู้เล่น ขณะนี้แผนที่ความสูงทดสอบที่ฉันใช้คือ 4096x4096 และบันทึกเป็น BMP 4 บิต

สิ่งที่ฉันพยายามจะทำคือนำไฟล์ heightmap ขนาดใหญ่มาแสดงในเกม ปัญหาที่ฉันพบคือความจริงที่ว่ามันไม่มีประสิทธิภาพในการโหลดภูมิประเทศทั้งหมดไปยังหน่วยความจำในครั้งเดียวเนื่องจากมันจะใช้หน่วยความจำส่วนใหญ่ที่มีอยู่

ปัญหาอีกประการหนึ่งที่ฉันพบคือฉันไม่สามารถทำให้ภูมิประเทศทั้งหมดเป็นแบบดั้งเดิมได้เนื่องจากมีการ จำกัด ฮาร์ดภายใน XNA

จากที่กล่าวมาฉันได้เจอวิธีแก้ปัญหาหลายอย่างซึ่งทั้งหมดได้ระบุไว้ด้านล่าง:

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

หลังจากลองใช้วิธีแก้ปัญหาเหล่านี้แล้วฉันก็ยังใหม่จากแนวคิดที่จะทำ ฉันได้รับคำตอบบางอย่างที่ผู้คนบอกให้ฉันทำอัลกอริทึมที่ซับซ้อนเหล่านี้ แต่ฉันก็ไม่รู้ว่าจะทำอย่างไร

โดยพื้นฐานแล้วฉันกำลังขอวิธีที่เรียบง่ายตรงไปตรงมาในการแสดงภูมิประเทศที่มีความเป็นมนุษย์ใน XNA ด้วยประสิทธิภาพสูงสุด

ฉันค่อนข้างใหม่สำหรับการพัฒนาเกมโดยทั่วไป แต่ฉันยินดีที่จะทำการวิจัยหากดูเหมือนว่ามีแนวโน้ม

อัปเดต 1:หลังจากค้นคว้าวิธีการ geoclipmapping ฉันเริ่มโค้ดด้วยวิธีนั้น ฉันทำคณิตศาสตร์ทั้งหมดเสร็จแล้วและเกมทำงาน อย่างไรก็ตามมันไม่มีประสิทธิภาพอย่างยิ่ง - ซึ่งอาจเป็นรหัสที่ไม่ดีในส่วนของฉัน มันทำงานที่ 2FPS และใช้ซีพียูทั้งหมดของฉัน ฉันจะลองและปรับปรุงรหัส แต่ฉันคิดว่าฉันต้องการความช่วยเหลือเพิ่มเติมดังนั้นนี่คือ Pastebin ของรหัสสำหรับคลาส Terrain manager ฉันจะโพสต์กลับด้วยผลลัพธ์เพิ่มเติมในภายหลังถ้าฉันได้รับมันจะมีประสิทธิภาพมากขึ้น


1
น่าสนใจเทคนิคที่คุณพูดถึงดูเหมือนจะคล้ายกับ ID Software ที่ใช้ในเกม Rage ที่กำลังจะมาถึง พวกเขาใช้ 'megatexture' แล้วสตรีมชิ้นส่วนของมันที่จำเป็นใน GPU เขาพูดถึงเรื่องนี้แล้ว แต่เป็นบทความวิกิพีเดียมันอาจเป็นแรงบันดาลใจ: en.wikipedia.org/wiki/MegaTexture

คำตอบ:


5

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

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

ตัวเรนเดอร์ภูมิประเทศที่สูงขึ้นใช้อัลกอริทึมในการปรับแต่งไม่เพียง แต่รูปทรงเรขาคณิตที่มองเห็นได้ แต่ยังแสดงรายละเอียดของรูปทรงเรขาคณิตนั้นด้วย Geomipmapping (และ geoclipmapping แบบสัมพัทธ์ของมัน) ได้รับความนิยมในขณะนี้สำหรับการทำเช่นนั้น แต่ไม่ใช่สิ่งเล็กน้อยที่จะนำมาใช้

แก้ไข: นี่คือคำอธิบายที่ดีของทั้ง geoclipmapping และ frullum การเลือกสรร

ฉันยังสงสัยด้วยว่าส่วนที่สูงของแผนที่ความสูงนั้นเพียงพอที่จะสร้างภูมิประเทศที่ดูดีหรือไม่ถ้าคุณไม่ได้ผลที่ตามมา


ฉันลองดูที่บทความนั้นและฉันตัดสินใจว่าฉันจะใช้วิธีการ geoclipmapping ก่อนเพราะมันดูเหมือนว่าจะมีประสิทธิภาพมากที่สุดในการแสดงภูมิประเทศจำนวนมาก ฉันจะโพสต์กลับด้วยผลลัพธ์ของฉัน

3

วิธีใดก็ตามที่คุณต้องทำงานต่อเฟรมเพื่อโหลดข้อมูลลงบน GPU จะมีข้อบกพร่อง

นี่เป็นโครงร่างคร่าวๆของวิธีหนึ่งที่ควรทำงานได้ดี

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

สำหรับภูมิประเทศ 4096x4096 คุณเกินขีด จำกัด เล็กน้อยที่ฉันสามารถโหลดได้อย่างสบายบน GPU ในครั้งเดียว - มันอาจเป็นข้อมูลจุดยอดไม่กี่ร้อย MB (แม้ว่าคุณจะสามารถลดได้ถึง ~ 64MB หากคุณ ฉลาด). ดังนั้นคุณอาจต้องโหลดและยกเลิกการโหลดบัฟเฟอร์จุดสุดยอดจาก GPU ในพื้นหลัง

(หากคุณใช้การโหลดพื้นหลังของชิ้นข้อมูลนี้ควรปรับขนาดได้อย่างมาก!)

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

คุณแทบไม่ควรทำอะไรต่อการเลือกสรรรูปสามเหลี่ยมบนซีพียู!

GPU ที่จะเฟ้นหารูปสามเหลี่ยมที่มีปิดหน้าจอมากได้เร็วขึ้นกว่าที่คุณเคยจะสามารถ

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับประสิทธิภาพลองดูที่คำตอบนี้บนเว็บไซต์ Game Dev


0

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


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