วิธีการเรนเดอร์ภูมิประเทศขนาดใหญ่อย่างมีประสิทธิภาพได้อย่างไร


10

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

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

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

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

ขออภัยสำหรับข้อผิดพลาดใด ๆ ฉันเป็นสามเณรมากในพื้นที่นี้

คำตอบ:


12

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

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

// Load vertices from disk
struct point { double x, y, z; };    
vector<point> vertices;

// Create container for chunks
typedef pair<int, int> key;
unordered_map<key, vector<point>> chunks;
const int chunksize = 10;

// For each vertex
for (int i = 0; i < vertices.size(); ++i) {
    // Fetch global coordinates
    int x = vertices[i].x,
        y = vertices[i].y,
        z = vertices[i].z;

    // Find containing chunk
    key k;
    k.first  = x / chunksize;
    k.second = z / chunksize;

    // Calculate local coordinates
    point p;
    p.x = x % chunksize;
    p.y = y;
    p.z = z % chunksize;

    // Add to chunk
    chunks[k].push_back(p);
}

// Create separate buffers for each chunk
// ...

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

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

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

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

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

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

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