ภูมิประเทศเรียบ Voxel


13

ในโครงการส่วนบุคคลฉันพยายามสร้างตัวสร้างภูมิประเทศที่จะสร้างภูมิประเทศที่ดูคล้ายกับภูมิประเทศที่ราบเรียบของ Castle Story

หากคุณไม่เคยเห็นมาก่อนนี่: ป้อนคำอธิบายรูปภาพที่นี่

อย่างที่คุณเห็นมันคือการรวมกันของบล็อกและบล็อก "ราบรื่น"

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

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

ปัญหาคือว่าแต่ละบล็อกมี 1x1x1 แต่บางครั้งความสูงของตำแหน่งใดตำแหน่งหนึ่งเป็นค่าลบหรือ> 1 ในกรณีนี้ฉันคลิปมันและตั้งค่าความสูงเป็น 0 หรือ 1

เพื่อแสดงให้เห็นถึงสิ่งที่ฉันหมายถึงนี่คือแผนภาพ: ป้อนคำอธิบายรูปภาพที่นี่

เพื่อสร้างความสูงฉันโดยทั่วไปทำ:

genColumn(int x, int z)
{
    int highestBlockY = (int)noise2d(x, z);

    bool is_surface = true;

    for(int y = max_height - 1; y >= 0; y--)
    {
        Block b;

        if(is_surface)
        {
            b = Block.Grass;
            b.HasHeightMap = true;

            // generate heightmap
            for(int ix = 0; ix < 5; ix++)
            {
                for(int iz = 0; iz < 5; iz++)
                {
                    float heightHere = noise2d(x + ix / 4, z + iz / 4) - y;

                    // clip heights
                    if(heightHere > 1)
                        heightHere = 1;

                    if(heightHere < 0)
                        heightHere = 0;

                    b.HeightMap[ix][iz] = heightHere;
                }
            }

            is_surface = false;
        }
        else
        {
            b = Block.Dirt;
        }

        setBlock(x, y, z, b);
    }
}

บางทีฉันกำลังเข้าใกล้สิ่งนี้อย่างไม่ถูกต้องโดยใช้ค่าสัญญาณรบกวน "จริง"

ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชมอย่างมาก!

คำตอบ:


11

Castle Story มีลักษณะเช่นนี้เนื่องจากข้อ จำกัด ทางเทคนิค: จะมี heightmap ต่อแต่ละ voxel ในปริมาณทั้งหมดแทนที่จะเป็นเพียง heightmap ต่อvoxel แต่ละพื้นผิวต้นทุนการจัดเก็บจะยิ่งใหญ่ขึ้นตามคำสั่งของ O (n ^ 3 ) ซึ่งสามารถห้ามได้ซึ่งตรงข้ามกับ O (n ^ 2) ที่ดีกว่าโดยที่ n คือความยาวด้านของพื้นที่ลูกบาศก์ voxel ที่แสดงถึงโลกของคุณ โปรดจำไว้ว่าข้อมูล heightmap สำหรับ subterranean voxels นั้นมีความหมายโดยนัยในโครงสร้างกริดดังนั้นข้อมูล heightmap ต้องถูกเก็บไว้อย่างชัดเจนสำหรับ voxels ที่อยู่บนพื้นผิวเท่านั้น ดังนั้นพวก Castle Story จึงถ่ายภาพจุดยอดเพื่อหยุดพักระหว่างทางเพื่อประหยัดค่าใช้จ่ายในการจัดเก็บและความซับซ้อนของโครงสร้างตาข่าย ... อ่านต่อ

ก่อนอื่นมาดูตัวเลือกของคุณ:

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

(1)กำลังจะทำให้สิ่งต่าง ๆ ยากสำหรับคุณเนื่องจากในคอลัมน์ voxel เดียวคุณต้องการข้อมูล mini-heightmap สำหรับvoxel สูงสุด - อ้างอิงกลับไปที่ย่อหน้าแรกด้วยเหตุผลว่าทำไม เมื่อดูที่ (1) คอลัมน์ทางด้านขวาจะมีข้อมูลความสูงของแผนที่ทั้งด้านบนและด้านบนจากด้านบน (ซึ่งอาจนำไปใช้กับคอลัมน์ที่สามจากบนสุดและอื่น ๆ ได้หากความชันนั้นมากพอ) มันไม่ดีเลย

(2)น่าจะเป็นตัวเลือกที่ดีกว่านี้; นั่นคือการทำให้แน่ใจว่าจุดยอดมุมนั้นชิดกับช่องว่างของตาราง voxel แต่เราจะแก้ไขปัญหาความชันที่รุนแรงได้อย่างไร? ทีนี้เราต้องเลือกการไล่ระดับสีที่เราเพียงแค่สแน็ปอินคอลัมน์แนวตั้งและทำให้แน่ใจว่าเราไม่มีการไล่ระดับสีเกินกว่าที่จะตัดผ่าน voxels สูงสุด การไล่ระดับสี 45 องศาเป็นทางลัดตามธรรมชาติด้วยเหตุผลที่ฉันอธิบายด้านล่าง ดังนั้นแทนที่จะ (3) เรามี (4):

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

(4)การตัดจุดยอดมุมของ voxel ไปยังจุดเชื่อมต่อกริดที่ใกล้ที่สุดคือวิธีแก้ปัญหา เอฟเฟกต์ภาพ - aliasing แนวทแยงมุม - สามารถมองเห็นได้ในสกรีนช็อตของ Castle Story ความชันของ cutoff สำหรับ voxels คือ 1: 1 gradient, หรือ 45 degrees (ตามที่ดู orthogonally) ทำงานย้อนกลับจากโซลูชันลองดูเหตุผล:

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

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


ฉันเพิ่งลองใช้สิ่งนี้และพบกับความสับสน - คุณหมายถึงอะไร "interstices" คุณหมายถึงพิกัดกริดแบบรวมหรือไม่?
ไม่มีชื่อ

@ThomasBradworth "ช่องว่างที่ขวางระหว่างสิ่งต่าง ๆ " สำหรับ 2D ถ้าคุณมีกริดของเซลล์ anxn คุณจะมี (n + 1) x (n + 1) interstices สิ่งนี้ขยายไปถึง 3D โดยตรง พวกเขาคือ "จุดยอด" ซึ่งผูกไว้กับแต่ละเซลล์ซึ่งส่วนใหญ่จะใช้ร่วมกันระหว่างหลายเซลล์ / voxels หากคุณต้มลงไปที่ 1D (หนึ่งบรรทัด) ถ้าทั้งเซลล์และ interstices ถูกแทนด้วยอาร์เรย์เซลล์ 0 จะถูกล้อมด้วย interstice 0 และ interstice 1 ในขณะที่เซลล์ 1 ถูกล้อมด้วย interstice 1 และ interstice 2 ... ฯลฯ
วิศวกร

ขอบคุณสำหรับการตอบกลับ! ฉันพยายามทำอย่างนั้น แต่ฉันได้ผลลัพธ์ที่ไม่พึงประสงค์ ตอนแรกฉันพยายามเพียงปัดเศษค่าความสูงที่ขอบ (เมื่อ x เป็น 0 หรือ 4 หรือ z เป็น 0 หรือ 4) แต่นั่นทำให้ฉัน: i.imgur.com/eQW7Y.png ( pastebin.com/Lr8vyyHB ) ต่อไปฉันพยายามปรับจุดตรงกลางให้เรียบดังนั้นฉันจึงเพิ่ม "ฟังก์ชั่นแก้ไขความสูง": pastebin.com/AazQ07Xmแต่อย่างไรก็ตามก็ให้เชิงมุมเพิ่มขึ้น แต่ก็ให้ผลที่แย่ด้วย: i.imgur.com/q1JVP .png บางทีมีบางอย่างผิดปกติกับฟังก์ชั่นเสียงรบกวนของฉัน
ไม่มีชื่อ

@ThomasBradsworth น่าเศร้าที่ฉันรู้สึกว่าคุณอ่านและเข้าใจคำตอบที่ฉันใช้เวลาเขียนและแก้ไขมากกว่าครึ่งชั่วโมง ลืมเสียงรบกวน นอกจากนี้หากคุณไม่เข้าใจฟังก์ชั่นเสียงรบกวนให้ลบออกจากสมการในตอนนี้ ปัญหาของคุณอยู่ที่การสร้างข้อมูลตาข่าย voxel แยกจากกันและเสียงไม่เกี่ยวข้องกับสิ่งนั้นเพราะคุณสามารถสร้างแผนที่ความสูงในกรณีที่ไม่มีสัญญาณรบกวน ทำงานกับกรณีทดสอบที่ง่ายที่สุดเช่น hardcode array height จากนั้นดูผลลัพธ์ของคุณและปรับแต่งอัลกอริทึมการสร้างตาข่ายของคุณ ทำซ้ำจนกว่าจะทำสิ่งที่คาดหวัง จากนั้นใส่เสียงกลับเข้าไปและทบทวน
วิศวกร

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