เครื่องยนต์ภูมิประเทศของ voxel สร้างขึ้นมาได้อย่างไร?


53

ไม่กี่วันที่ผ่านมาฉันพบสิ่งที่เรียกว่า voxel terrains และฉันคิดว่ามันค่อนข้างเท่ห์ แต่ฉันไม่รู้จะสร้างอะไรขึ้นมา คุณสร้างแบบจำลองในซอฟต์แวร์การสร้างแบบจำลองของคุณหรือใช้สิ่งที่ต้องการความสูงหรือไม่ ฉันอ่านวิกิพีเดียว่า voxels เหมือนพิกเซล 3 มิติหรือพิกเซลเชิงปริมาตร

หลังจากที่ผมทำให้ภูมิประเทศ voxel วิธีฉันสามารถใช้ชุเหล่านี้และทำให้พวกเขา destroyable / diggable ?


ฉันจะเลือกคำตอบที่ดีที่สุดตาม:

  1. รหัสและอัลกอริทึม โดยเฉพาะอย่างยิ่งใน C #
  2. คำอธิบาย ฉันเป็นมือใหม่ที่มีอัลกอริธึม แต่ฉันคุ้นเคยกับการเขียนโปรแกรมเชิงวัตถุมาก
  3. การสาธิตทีละขั้นตอน ไม่เพียง แต่แนวคิด แต่เป็นทิศทาง
  4. แผนภาพ / ภาพประกอบ ไม่ไม่ใช่ภาพหน้าจอของเอ็นจินอื่น ๆ


ฉันรู้ว่านี่เป็นเรื่องที่ซับซ้อน แต่ขอบคุณสำหรับความช่วยเหลือ!

ไม่ฉันไม่ได้พยายามสร้าง minecraft โคลน


แก้ไข

ขอบคุณทุกคนสำหรับความช่วยเหลือที่ดีของคุณ (โดยเฉพาะ Nick Wiggill)! นี่คือสิ่งที่ฉันจัดการเพื่อให้ (กำลังดำเนินการ)


[สามัคคี] และC ? นั่น ... ทำให้รู้สึกน้อย
Martin Sojka

ฉันเข้าใจ C.
Daniel Pendergast

8
คุณมีศรัทธาในชุมชนมากมายด้วยการร้องขอที่กล้าหาญ ฉันหมายถึงกระดาษฉบับสมบูรณ์ในภูมิประเทศ voxel แบบไดนามิกสำหรับฮาร์ดแวร์ของวันนี้ด้วย FPS ที่ดีมันควรจะง่ายใช่มั้ย หัวข้อนี้กว้างและยากมากฉันสงสัยว่าคุณจะเห็นวิธีแก้ปัญหาทั่วไปและถึงตอนนั้นมันอาจไร้ประโยชน์โดยสิ้นเชิงสำหรับกรณีของคุณ แต่ใครจะรู้ก็อาจทำได้ขึ้นอยู่กับแบบอย่างของคุณ คุณต้องการภูมิประเทศCrysis 2 voxel หรือDelta Force one หรือไม่? บางทีคุณกำลังทำโคลนMinecraftหรือแค่ต้องการจำลองทรายสำหรับเกมขุด? กรุณากำหนดขอบเขต
EnoughTea

2
ตรวจสอบมิดเดิลแวร์นี้: forum.unity3d.com/threads/... โดยเฉพาะอย่างยิ่งการสาธิต
Tetrad

1
GPU Gems 3 มีเนื้อหาเกี่ยวกับภูมิประเทศ voxel: http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html
Tamschi

คำตอบ:


58

เพื่อสร้างภูมิประเทศ voxel

(a)วิธีการทั่วไปคือการสร้าง heightmap โดยใช้สัญญาณรบกวน Perlin ความสูงนั้นเป็นภาพขาวดำที่แสดงความสูงต่างกันโดยความมืดหรือความสว่างของพิกเซล

ป้อนคำอธิบายรูปภาพที่นี่

คุณจะดูที่พิกเซลแต่ละอันในแผนที่ความสูงนี้เพื่อสร้าง "สแต็ค" ของ voxels สูงถึงความสูงที่แตกต่างกัน (แกน z) ในสถานที่ที่แตกต่างกัน (x, y) ตามความสว่างของพิกเซลนั้นในรูปภาพของแผนที่ความสูง เนื่องจากภาพสัญญาณรบกวนของ Perlin นั้นราบรื่น (ไม่มีขอบที่คมชัดเมื่อเทียบกับความมืด) คุณจะได้ภูมิประเทศที่ราบรื่น

(b)คุณสามารถสร้างมันทีละส่วนได้โดยการสร้างภูมิทัศน์จากรูปทรงหลายเหลี่ยมที่แตกต่างกัน สร้างรูปร่างเวกเตอร์ polyhedral ที่ใกล้เคียงกับรูปร่าง voxel ที่คุณต้องการ ใช้วิธี 3D-point-in-polyhedron (ส่วนใหญ่เป็นจุดนูน - ฮัลล์) ตรวจสอบว่าจุดใดในตารางโลกของคุณตกอยู่ในปริมาตร polyhedral นั้น ตัวอย่างเช่นกำหนดปิรามิดในอวกาศ หลังจากตรวจสอบทุกจุดในพื้นที่ท้องถิ่นของพื้นที่โลกของคุณกับปริมาตรพีระมิดนั้นคุณจะรู้ว่าจุดใดที่อยู่ภายในและคุณสามารถตั้งค่าเซลล์เหล่านั้นให้เป็น "ปัจจุบัน" ซึ่งหมายความว่าพวกมันกลายเป็น voxels แทนพื้นที่ว่าง ตอนนี้คุณมีปิรามิด voxel ในอวกาศของคุณ คุณสามารถเพิ่มรูปร่างของการเรียงลำดับใด ๆ ต่อไปได้ด้วยวิธีนี้จนกว่าคุณจะได้สร้างภูมิประเทศ

(c) (จริงๆเหมือนกับb ) เขียนเครื่องมือสร้างแบบจำลอง Voxatronแสดงให้เห็นว่ามันจะเป็นอย่างไร นี่เป็นเพียงการสร้างรูปแบบ voxel ในโลกแห่งการทดแทน (บรรณาธิการ) แล้วนำเข้าสิ่งเหล่านี้เข้าสู่โลกเกมรันไทม์ที่แท้จริงของคุณ ฉันเชื่อว่าVoxlapมีเครื่องมือแก้ไขโอเพ่นซอร์สตัวแรกสำหรับ voxels คุณสามารถวาง voxels เดี่ยว ๆ หรือคุณสามารถใช้ "แปรง" voxel ที่มีรูปร่าง / ปริมาณที่แตกต่างกันเพื่อดึง voxels เข้าสู่โลกของคุณ


สิ่งที่คุณจะต้องสร้างเกมที่ใช้ voxel ของคุณเอง

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

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

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

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

  • ชุตามตาข่ายลูกบาศก์ ( ตัวอย่าง ) - เหล่านี้เป็นจัดเรียงใหม่ที่ใช้สำหรับความเรียบง่ายและใช้งานได้อย่างง่ายดายร่วมกับกราฟิกที่ทันสมัยไฮเทค ใช้ในเกมเช่น MineCrat และ Dungeon Keeper
  • ชุพอยต์ ( ตัวอย่างเช่น , ตัวอย่าง ) - The voxel เดิม แต่ละจุดเป็นจุดแยกส่วนบุคคลในอวกาศแม้ว่ามันอาจจะถูกล้อมรอบด้วยปริมาตรขอบเขตทรงกลม มันง่ายกว่าดังนั้นคุณสามารถมีพวกมันได้มากมายในโลกของคุณและคุณสามารถทำให้มันเล็กลงซึ่งโดยทั่วไปแล้วเป็นสิ่งที่ดี สองเกมที่ใช้สิ่งเหล่านี้คือ Comanche และ 1990's remake of Lords of Midnight

ไม่ว่าจะด้วยวิธีใดวิธีการจัดการกับ voxels ในโลกของคุณก็เหมือนกันดังนี้

ในการสร้างและย้ายวัตถุในโลกของคุณคุณจะต้องใช้เครื่องมือทางคณิตศาสตร์ที่กล่าวถึงข้างต้น ตัวอย่างเช่นในการสร้างกำแพง: สร้างกล่องขนาดที่เหมาะสมในพื้นที่ 3D โดยใช้เวกเตอร์ ใช้เมทริกซ์คณิตศาสตร์เพื่อแปลงกล่องของคุณเป็นการหมุนและตำแหน่งที่คุณต้องการในโลก 3 มิติของคุณ (ในปริภูมิเวกเตอร์ต่อเนื่อง) สำหรับเอ็นจิ้น voxel ขั้นตอนเพิ่มเติมคือตอนนี้ใช้อัลกอริธึมแบบ point-in-polyhedron แบบ 3D เพื่อกำหนดว่า voxels ใดที่อยู่ในพื้นที่หมุนรอบนั้น

นี่คือวิธีที่คุณจะสร้างวัตถุส่วนใหญ่ในโลกของคุณ นอกเหนือจากนั้นคุณสามารถเขียนเครื่องมือของคุณเองเพื่อ "จำลอง" ตัวละครในแบบที่คุณอาจพูด Maya หรือ 3DS Max แต่เนื่องจากคุณกำลังสร้างโมเดลคุณจะทำให้ตัวละครไม่มี voxels แทนที่จะเป็นจุดขอบและใบหน้าวิธีการของคุณจะแตกต่างกันอย่างมาก หากคุณตัดสินใจที่จะหมุนวัตถุเหล่านี้ในโลกของคุณคุณจะต้องใช้การแปลงเมทริกซ์ในทำนองเดียวกันเพื่อทำเช่นนั้น

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

ในการที่จะมีวัสดุ "ไหล" (ตามที่ Vigil บอกไว้ในความคิดเห็นของเขาบนทราย) คุณจะต้องมองเข้าไปในพลศาสตร์ของไหลและออโตมาตาของเซลล์ สิ่งเหล่านี้ถูกใช้โดยผู้เขียนของ Dwarf Fortress, Tarn Adams ในสิ่งที่เป็นหลักของโลก voxel (แม้ว่า voxels จะมีขนาดใหญ่กว่ามากในกรณีนี้เปรียบได้กับ Dungeon Keeper หลักการยังคงเหมือนเดิม) เหล่านี้เป็นหัวข้อที่ทันสมัยและไม่จำเป็นสำหรับเครื่องยนต์ voxel ตามที่กำหนดดังนั้นฉันจะปล่อยให้สิ่งนี้เป็น "stub" สำหรับการวิจัยของคุณเอง

CSG และพลศาสตร์ของไหลนำมาซึ่งการเพิ่มประสิทธิภาพ เครื่องมือ Voxel กำลังอยู่ในระหว่างการพัฒนาใช้ประโยชน์จาก sparse voxel octrees (SVOs) ซึ่งเป็นวิธีการแบ่งพื้นที่ voxel ไปสู่การแก้ปัญหาที่แตกต่างกันตามที่ปรากฏในวิดีโอนี้ซึ่งแสดงให้เห็นถึงเครื่องยนต์ Atomontage ที่กำลังจะมาถึง การใช้ octrees / SVO นั้นมีความจำเป็นมากกว่าตัวเลือกการปรับให้เหมาะสมที่สุดเนื่องจากการประมวลผลค่าโสหุ้ยที่เกี่ยวข้องกับการประมวลผลกริดขนาดใหญ่หนึ่งชุด octree เป็นต้นไม้ (กราฟ acyclic กำกับ) ที่ทุกโหนดมีโหนดลูก 8 หรือศูนย์ขึ้นอยู่กับว่าพื้นที่ที่มันหมายถึงมีปริมาณทางกายภาพใด ๆ แผนภาพแสดงให้เห็นว่า octrees แบ่งพื้นที่ในรูปแบบชุอยู่ที่นี่

การใช้ voxel แบบโอเพ่นซอร์สที่ดีที่สุดที่ฉันรู้จักคือVoxlap Engineของ Ken Silverman ซึ่งใช้สำหรับ Voxelstein3D มันเขียนใน C ++ และดำเนินการกับ CSG สำหรับการเปลี่ยนรูปภูมิประเทศ


การเปลี่ยนแปลงของวิกิชุมชนนั้นถาวรไม่มีทางที่จะย้อนกลับได้ คุณจะต้องลบและสร้างคำตอบของคุณใหม่ (แน่นอนว่าเป็นการเสียสละคะแนนที่มีอยู่ของคุณ)
Jesse Dorsey

meta.stackexchange.com/questions/2974/…อ้างว่าผู้ดูแลสามารถลบได้ ไม่ทราบว่ามีการเปลี่ยนแปลงหรือไม่ ขอบคุณที่มองมันเป็นอย่างใด
วิศวกร

1
ไปคิดให้รอบคอบในครั้งต่อไป
Jesse Dorsey

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

1
การทำพื้นผิวโดยปริยาย voxels จริงไม่ว่าจะเป็นตาข่ายหรือไม่ก็ตามแต่ละสีมีความบริสุทธิ์ วิธีการดังกล่าวข้างต้นเพียงสร้างรายละเอียดที่สมจริงมากขึ้นและเปิดใช้วิธีการแบบรวมตาข่าย (google Unity VoxelForm) ยิ่ง voxels ของคุณละเอียดยิ่งขึ้นรายละเอียดพื้นผิวผลลัพธ์ของคุณจะดีขึ้น ตัวอย่าง: ทำแบบจำลองเตียงริมแม่น้ำเป็นหิน (สีเทา) แปลงทุกพิกเซลในระยะ x ของพื้นผิวเป็นทรายโดยการตั้งค่า voxels เหล่านี้ให้มี material = "sand"; จากนั้นพวกเขาสามารถแสดงผลเป็นสีทราย นอกจากนี้สิ่งนี้อาจส่งผลกระทบต่อการโต้ตอบทางกายภาพของพวกเขาดังนั้นทรายอาจถูกเคลื่อนย้ายด้วยน้ำหรือขุดออกไป
วิศวกร

33

วิธีที่ดีที่สุดในการสร้างภูมิประเทศ voxel ที่น่าสนใจคือแผนที่ Perlin noise ที่มีความหนาแน่น แทนที่จะใช้แผนที่เสียง 2D Perlin ที่กำหนดความสูงของโลก 3 มิติให้ใช้แผนที่เสียง 3D Perlin ชั่งน้ำหนักแผนที่เพื่อให้ค่าที่อยู่ใกล้กับด้านล่างมากขึ้นจะเป็นของแข็งมากขึ้นและค่าที่อยู่ใกล้กับด้านบนจะมีการออกอากาศอย่างแน่นอน สิ่งนี้จะทำให้ความสูงของโลกของคุณ แต่ยังช่วยให้ยื่นและถ้ำคล้ายกับภูมิประเทศ Minecraftเป็นมุมมองด้านข้างของชิ้นภูมิประเทศที่แสดงให้เห็น:

โลกที่มีสิ่งที่แขวนอยู่

จากที่นี่คุณสามารถทดสอบเกาะลอยน้ำหรือเพิ่มระบบถ้ำด้วยเสียงเศษส่วน:

โลกที่มีระบบถ้ำ

ภาพข้างบนและแนวคิดระบบถ้ำมาจากโพสต์บล็อกที่ยอดเยี่ยมนี้ คุณสามารถเรียนรู้ทุกอย่างเกี่ยวกับ Perlin เสียงที่นี่และมีตัวอย่างโค้ดบางส่วนที่จะได้รับคุณเริ่มต้นที่นี่


4

คำตอบอื่น ๆ ที่นี่ยอดเยี่ยม แต่ฉันใช้วิธีที่แตกต่างกันเล็กน้อย

ฉันสร้างสภาพแวดล้อมในเครื่องมือสร้างแบบจำลอง (3DSMAX) และสร้าง octree กระจัดกระจายจากมัน โหนดใบไม้แบบลูกบาศก์ที่ไม่ว่างเปล่าแต่ละโหนดเป็น voxel ณ เวลาเรนเดอร์ฉันใช้ raycasting (นำไปใช้ใน HLSL) เพื่อค้นหา voxel ที่ใช้พิกเซลตัวใดและตั้งค่าพิกเซลเป็นสีที่เก็บไว้ในโหนดซึ่งฉันคำนวณเมื่อสร้างต้นไม้โดยเฉลี่ยค่าพื้นผิวจากโมเดลต้นทาง

สิ่งนี้ให้ประโยชน์ที่ดีมากมายแก่คุณ - การตรวจจับการชนสำหรับฟรี, LOD ที่ผันแปร, การดูพื้นที่ที่คัดออก, ฯลฯ - และนอกเหนือจาก raycaster - มันใช้งานง่าย

น่าเสียดายที่มันเป็นไปไม่ได้ที่จะโพสต์ตัวอย่างโค้ดจากโทรศัพท์


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

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