โครงสร้างข้อมูลใดที่ควรใช้เพื่อเป็นตัวแทนของภูมิประเทศ voxel


18

ตามหน้า Wikipediaเกี่ยวกับ voxels "[... ] ตำแหน่งของ voxel นั้นอนุมานตามตำแหน่งของมันเมื่อเทียบกับ voxels อื่น ๆ (เช่นตำแหน่งของมันในโครงสร้างข้อมูลที่ทำขึ้นเป็นรูปปริมาตรเดียว)"

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


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

คำตอบ:


14

เป็นครั้งแรก ให้เขียนสิ่งที่เรารู้เกี่ยวกับแต่ละ voxel:

voxel = (x, y, z, color) // or some other information

ที่เก็บข้อมูลทั่วไป

วิธีทั่วไปเป็นเพียงแค่นี้:

set of voxels = set of (x,y,z, color)

โปรดทราบว่า triplet (x, y, z) ระบุแต่ละ voxel ที่ไม่ซ้ำกันเนื่องจาก voxel เป็นจุดในอวกาศและไม่มีวิธีที่สองจุดครอบครองที่เดียว (ฉันเชื่อว่าเรากำลังพูดถึงข้อมูล voxel คงที่)

มันควรจะดีสำหรับข้อมูลที่เรียบง่าย แต่มันก็ไม่ได้เป็นโครงสร้างข้อมูลที่รวดเร็ว

การแสดงผลเป็น AFAIK ทำโดยอัลกอริทึม scanline บทความฮาร์ดแวร์ของทอมในชุมีภาพของอัลกอริทึม scanline

ค้นหาอย่างรวดเร็ว

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

array [x][y][z] of (color)
  • นี่คือ O (1) เพื่อค้นหา voxel โดย x, y, z พิกัด

  • ปัญหาคือว่ามันต้องการพื้นที่คือ O (D ^ 3) โดยที่ D คือช่วงของแต่ละจำนวน x, y และ z (ลืมจำนวนจริงเนื่องจากถ้าพวกเขาเป็น Chars ซึ่งมีช่วง 256 ค่าจะมี 256 ^ 3 = 2 ^ 24 == 16 777 216 องค์ประกอบในอาร์เรย์)

แต่มันขึ้นอยู่กับสิ่งที่คุณต้องการจะทำกับ voxels ถ้าการเรนเดอร์เป็นสิ่งที่คุณต้องการมันก็น่าจะเป็นอาเรย์ที่คุณต้องการ แต่ปัญหาของการจัดเก็บยังคงอยู่ ...

หากที่เก็บข้อมูลมีปัญหา

วิธีหนึ่งคือการใช้การบีบอัด RLE ในอาร์เรย์ ลองนึกภาพชิ้นส่วนของ voxels (ชุดของ voxels โดยที่ voxels มีค่าพิกัดหนึ่งค่าคงที่ .... เช่นระนาบที่ z = 13 เป็นต้น) เช่นชิ้นของชุจะมองเหมือนการวาดภาพง่ายๆใน MSPaint ฉันจะบอกว่าแบบจำลองของ Voxel มักจะอยู่ในตำแหน่งที่เป็นไปได้ทั้งหมด (D ^ 3 พื้นที่ของ voxels ที่เป็นไปได้ทั้งหมด) ฉันเชื่อว่า "ใช้คู่จาก triplet ของพิกัดและบีบอัดแกนที่เหลืออยู่" จะทำกลอุบาย (เช่นใช้ [x] [y] และสำหรับแต่ละองค์ประกอบบีบอัด voxels ทั้งหมดที่แกน z ที่ x, y .. . ควรมี 0 ถึงองค์ประกอบไม่กี่ RLE จะทำอะไรดีที่นี่):

array [x][y] of RLE compressed z "lines" of voxel; each uncompressed voxel has color 

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

tree data structure  = recursively classified voxels
for octrees: recursively classified by which octant does voxel at (x,y,z) belong to
  • Octree ตามที่ Nick พูดถึง มันควรบีบอัด voxels Octree มีความเร็วที่พอเหมาะสำหรับการค้นหาฉันคิดว่ามันเป็น O (log N) โดยที่ N คือจำนวน voxels
  • Octree ควรสามารถจัดเก็บข้อมูล voxel ตามอำเภอใจได้อย่างเหมาะสม

หาก voxels เป็นบางส่วนของความสูงแบบง่ายๆคุณอาจเก็บไว้ที่ หรือคุณอาจเก็บพารามิเตอร์เพื่อทำงานซึ่งสร้างแผนที่ความสูงหรือที่เรียกว่าสร้างแบบเป็นขั้นตอน ...

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

TL; DR

นอกเหนือจาก Octrees คือการบีบอัด RLE ด้วย voxels, google "voxlap", "ken silverman" ...

ทรัพยากร

มีรายชื่อของเป็นทรัพยากรและการอภิปรายเกี่ยวกับวิธีที่จะทำให้ renderer voxel ได้อย่างรวดเร็วรวมถึงเอกสารและรหัสแหล่งที่มา


1
"ถ้าที่เก็บข้อมูลมีปัญหา": คุณสามารถใช้ VTC ( oss.sgi.com/projects/ogl-sample/registry/NV/ … ) หรือการบีบอัด DXT
KindDragon

@KindDragon ขอบคุณสำหรับข้อมูลนี้ :) นั่นเป็นความคิดที่ดีมาก
user712092

ลิงก์ทรัพยากรไม่ทำงาน
Ezequiel

4

มีโครงสร้างข้อมูลที่แตกต่างกันสองด้านที่พวกเขาอาจพูดถึง

โครงสร้างอาเรย์

เมื่อคุณอ้างอิงองค์ประกอบของอาเรย์ของจำนวนมิติใด ๆ ให้พิจารณาว่าอาเรย์นั้นเมื่อคุณผ่านดัชนี (เช่น. myArray[4][6][15]) จะรู้ว่ามีอะไรอยู่ในตำแหน่งนั้น ถ้าสิ่งที่อยู่ในสถานที่นั้นเป็น voxel, voxel นั้นไม่จำเป็นต้องบันทึกเพิ่มเติมเป็นพิกัด x, y, และ z ของตัวเอง - อาร์เรย์ที่เก็บ voxel ระบุว่าเป็นตำแหน่งโลกโดยปริยายโดยขึ้นอยู่กับตำแหน่งดัชนีอาเรย์

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

Octrees

(ฉันสังเกตเห็นสิ่งที่สองนี้เพราะสิ่งนี้มีความเป็นไปได้น้อยกว่าที่วิกิพีเดียอ้างถึงและการใช้งาน voxel ไม่ต้องการการใช้ octrees แม้ว่าผู้ที่ทันสมัยเกือบทั้งหมดจะใช้ octrees)

โหนดรูตของ octree เป็นคิวบ์เดี่ยวที่ไม่มีการแบ่งแยก ลองตั้งค่าตัวอย่าง พูดว่ารากของแปดของคุณซึ่งเป็นศูนย์กลางของลูกบาศก์อยู่{0, 0, 0}ในพื้นที่ 3 มิติ เมื่อคุณเริ่มวางวัตถุภายในพื้นที่นั้น (อ่านแล้ว: วัตถุมากกว่าหนึ่งวัตถุ) ก็ถึงเวลาที่จะแยกส่วนที่แปดออกไปอีก นี่คือที่ที่คุณแบ่งออกเป็น 8 ( ตุลาคม - ) โดยแบ่งมันออกเป็น 3 ระนาบระนาบเหล่านี้คือระนาบ xy, xz และ yz คิวบ์ดั้งเดิมของคุณมีขนาดเล็กลง 8 ก้อนอย่างแน่นอน แต่ละเหล่านี้โหนดย่อยมีตำแหน่งเป็นชดเชยจากภาคกลางก้อนปกครอง นั่นคือตัวอย่างเช่นลูกบาศก์ที่อยู่ใน xyz octant บวกจะมีการชดเชยจากผู้ปกครอง / ที่มีศูนย์กลางของ cube เท่ากับ{root.width / 4, root.height / 4, root.depth / 4}. แทนที่จะระบุตำแหน่งที่แน่นอนสำหรับแต่ละโหนดย่อยมันสมเหตุสมผลมากกว่าที่จะพิจารณาโหนดหลักเป็นจุดกำเนิดของพื้นที่ย่อยของเด็ก นี่เป็นวิธีเดียวกับที่กราฟของฉากทำงาน

มันง่ายพอที่จะเห็นสิ่งนี้ในรูปวาด 2D ซึ่งคุณวาดสี่เหลี่ยมและแบ่งออกเป็น 4 ภูมิภาคเท่ากัน ถ้าเช่นเดียวกับโหนดรากแปดของเราจุดศูนย์กลางของตารางหลักถูกพิจารณาว่าเป็น{0, 0}แล้ว 4 ศูนย์กลางของช่องสี่เหลี่ยมเด็ก

{root.width / 4, root.height / 4}, {-root.width / 4, root.height / 4}, {root.width / 4, -root.height / 4}, {-root.width / 4, -root.height / 4}

... เมื่อเทียบกับพ่อแม่ - หลักการเดียวกับใน 3D


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

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

การอ่านเพิ่มเติมการอภิปรายที่ดีเกี่ยวกับการใช้งานของ octrees รวมถึงการอ้างอิงที่มีประโยชน์มากมายสามารถดูได้ในบทความExtending the STL for Gamesของ Intel
Martin Foot

1

คุณสามารถใช้ RLE แต่คุณสามารถใช้ SVO (Sparse Voxel Octree), id Tech 6 ใช้ SVO SVO เป็นเทคนิคการเรนเดอร์กราฟิกคอมพิวเตอร์ 3 มิติโดยใช้วิธีการเรย์แคสต์หรือบางครั้งวิธีการติดตามเรย์ในการแสดงข้อมูลที่แปด

เทคนิคแตกต่างกันไปบ้าง แต่โดยทั่วไปจะอาศัยการสร้างและประมวลผลฮัลล์จุด (sparse voxels) ซึ่งสามารถมองเห็นได้หรืออาจมองเห็นได้ให้ความละเอียดและขนาดของหน้าจอ

ใช้ raycasting เพราะมันเร็วกว่า


0

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

นี่คือสิ่งที่ฉันใช้เวลาทำนาน: http://sites.google.com/site/williamedwardscoder/spinning-voxels-in-flash

หากภูมิประเทศของคุณมีสิ่งที่แขวนอยู่หรือถ้ำหรือคุณสมบัติอื่น ๆ จำนวนน้อยที่ไม่สามารถแสดงด้วยความสูงแผนที่ได้คุณสามารถมีรูในความสูงแผนที่ของคุณและมีการแสดงทางเลือกอื่น ๆ เช่นวัตถุ voxel 3D จริง ๆ ได้รับการรับประกัน

การกระจัดกระจายของ Voxelนั้นคุ้มค่าเมื่อคุณมีโลก Voxel ขนาดใหญ่ John Carmackพูดคุยกับพวกเขามาหลายปีแล้ว ...


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