สร้าง Octree สำหรับการสร้างภูมิประเทศ


9

ก่อนหน้านี้ฉันได้ใช้การเดินขบวน cubes / tetrahedra เพื่อสร้าง IsoSurface มันใช้งานได้ ( YouTube ) แต่ประสิทธิภาพการทำงานแย่มากเพราะฉันไม่เคยได้รับการใช้งานระดับรายละเอียดที่แปรผันตามระยะทางในการดู

ฉันตัดสินใจที่จะมีอีกไปและทำอย่างถูกต้องในเวลานี้ ฉันเริ่มต้นด้วยการสร้าง OctreeNode ที่ทำงานดังนี้เมื่อBuild()ถูกเรียก

  • หากชิ้นเล็กเกินไปที่จะสร้างกลับมาทันที
  • ทำงานถ้าพื้นผิวผ่านปริมาตรอันนี้
  • ถ้าเป็นเช่นนั้นตัดสินใจว่าเราต้องการยก LOD (เพราะกล้องปิด)
  • ถ้าเป็นเช่นนั้นให้วางไข่เด็ก 8 คนและเรียกกระบวนการเดียวกันกับพวกเขา
  • ถ้าไม่สร้างตาข่ายโดยใช้ขนาดของโหนดปัจจุบัน

บาง PseudoCode:

OctNode Build() {
    if(this.ChunkSize < minChunkSize) {
        return null;
    }
    densityRange = densitySource¹.GetDensityRange(this.bounds);
    if(densityRange.min < surface < densityRange.max) {
        if(loDProvider.DesiredLod(bounds > currentLoD) {
            for(i 1 to 8) {
                if(children[i] == null) {
                    children[i] = new OctNode(...)
                }
                children[i] = children[i].Build();
            }
        } else {
            BuildMesh();
        }
        return this;
    }
}

¹เช่นเดียวกับความหนาแน่นกลับมาที่จุดแหล่งความหนาแน่นสามารถกำหนดช่วงความหนาแน่นที่เป็นไปได้สำหรับปริมาณที่กำหนด

²ผู้ให้บริการ LoD รับกล่องขอบเขตและคืนค่า LoD ที่ต้องการสูงสุดตามตำแหน่ง / frustum ของกล้องการตั้งค่าผู้ใช้ ฯลฯ ...

ดังนั้น ... ทั้งหมดนี้ใช้งานได้ดี การใช้ทรงกลมง่ายๆเป็นแหล่งความหนาแน่นและแสดงโหนดทั้งหมด:

เต็มแปด

และเพียงแค่ใบไม้:

Octree แสดงเฉพาะใบไม้

อย่างไรก็ตามมีปัญหาสองสามประการ:

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

ฉันคิดว่ามีสองตัวเลือก แต่ทั้งคู่ดูเหมือนจะมีข้อบกพร่อง:

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

¹ [โดยการชี้แจงต่อ Q ด้านล่าง] ปัจจุบันถ้า 2 โหนดที่อยู่ติดกันในต้นไม้มี LOD ที่ต่างกันฉันมีรหัสที่จะบีบบังคับให้ verts ที่ไม่มีรอยต่อเมื่อตาข่ายถูกสร้างขึ้น ฉันสามารถทำได้โดยการรู้ความหนาแน่นของหลาย ๆ โหนด ในสถานการณ์ที่ฉันมีสองอิสระแปดด้านข้างกันฉันไม่มีวิธีที่ง่ายในการดึงข้อมูลนี้ทำให้เกิดตะเข็บ

อะไรคือวิธีที่เหมาะสมที่สุดในการเข้าถึงสิ่งนี้

คำตอบ:


1

ฉันไม่แน่ใจว่าฉันกำลังตอบคำถามที่แน่นอนดังนั้นฉันจะตอบในส่วนและรู้สึกอิสระที่จะตอบความคิดเห็นหากมีความเข้าใจผิดเกี่ยวกับรายละเอียดของคำถามเฉพาะ

ฉันต้องกำหนดปริมาณการเริ่มต้นขอบเขต (และยิ่งมีขนาดใหญ่ขึ้นการประมวลผลเพิ่มเติมที่ฉันต้องทำ)

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

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

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

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

ดังที่ฉันเข้าใจแล้วโซลูชันที่เสนอนี้เกี่ยวกับการลด LoD เมื่อย้ายออกจากพื้นที่ที่มีรายละเอียดก่อนหน้านี้ ฉันคิดว่ามันควรจะดูคล้ายกับเส้นทางโค้ด "เพิ่ม LoD":

if (loDProvider.DesiredLod(bounds) <(is a lot less than)< currentLoD) { 
    for(i = 1 to 8) { 
        children[i].Destroy();
    }
    BuildMesh();
}

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


สมมติว่าโหนดเล็ก ๆ นั้นเป็นก้อนหินนั่นอาจหมายถึงหลายสิบถ้าไม่นับหลายร้อยระดับเมื่อฉันเดินทางข้ามทวีป

ฉันคิดว่าสเกลลอการิทึมของ octree ทำให้ยังคงเป็นไปได้ หากระดับสูงสุดของคุณกว้าง 1,000,0000,000 เมตร (นี่จะกว้างกว่าโลกจริง 25 เท่าและมีพื้นที่ผิว 625 เท่า) และบิตระดับต่ำสุดของคุณอยู่ที่ 10 ซม. นั่นคือ 32 ระดับในเดือนตุลาคมซึ่งอาจเป็นจัดการได้เพียงพอ หากคุณต้องการดาวเคราะห์ที่กว้างกว่าโลก 100 เท่า (และมีพื้นที่ผิวมากกว่า 10,000 เท่า) นั่นเป็นเพียงระดับเพิ่มอีก 3-4 ระดับในเดือนตุลาคมของคุณ ณ จุดนี้มันจะใช้เวลาผู้เล่นหลายร้อยปีที่จะเดินข้ามโลกและถ้าคุณใช้คณิตศาสตร์จุดลอยตัวไร้เดียงสาโลกจะสะสมข้อผิดพลาดที่มีความแม่นยำ

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

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


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

เท่าที่ผู้เล่นกังวล "หนึ่งพันล้านไมล์" นั้นค่อนข้างใกล้เคียงกับ "อนันต์" ข้อโต้แย้งเพิ่มเติมสำหรับปริมาณเริ่มต้นคงที่ที่จะตอบ
จิมมี่

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