Làm thế nào để tải khối chunk trên bay?


8

Tôi hiện đang làm việc trên một thế giới vô tận, chủ yếu lấy cảm hứng từ minecraft.
Một Chunk bao gồm các khối 16x16x16. Một khối (khối) là 1x1x1.

Điều này chạy rất mượt mà với ViewRange 12 Chunks (12x16) trên máy tính của tôi. Khỏe.
Khi tôi thay đổi chiều cao Chunk thành 256, điều này trở nên - rõ ràng - độ trễ đáng kinh ngạc.

Vì vậy, những gì tôi về cơ bản muốn làm là xếp chồng chunk. Điều đó có nghĩa là thế giới của tôi có thể là [, 16,] Chunks rộng lớn.

Câu hỏi bây giờ là làm thế nào để tạo khối khi đang bay?
Tại thời điểm này, tôi tạo ra các khối không tồn tại xung quanh vị trí của mình (gần đến xa). Vì tôi chưa xếp các khối, nên điều này không phức tạp lắm.

Như lưu ý phụ quan trọng ở đây: Tôi cũng muốn có quần xã, với chiều cao tối thiểu / tối đa khác nhau. Vì vậy, trong Biome Flatlands , lớp cao nhất với các khối sẽ là 8 (8x16) - ở Biome Mountains , lớp cao nhất với các khối sẽ là 14 (14x16). Chỉ là ví dụ.

Những gì tôi có thể làm sẽ là tải 1 Chunk ở trên và dưới tôi chẳng hạn.
Nhưng vấn đề ở đây là, sự chuyển tiếp giữa các sinh vật khác nhau có thể lớn hơn một đoạn trên y.




Chuyển đổi giữa các quần xã




Tải chunk hiện tại của tôi trong hành động

Ví dụ tải chunk



Để hoàn thiện ở đây, "thuật toán" tải chunk hiện tại của tôi

private IEnumerator UpdateChunks(){
    for (int i = 1; i < VIEW_RANGE; i += ChunkWidth) {
        float vr = i;
        for (float x = transform.position.x - vr; x < transform.position.x + vr; x += ChunkWidth) {
            for (float z = transform.position.z - vr; z < transform.position.z + vr; z += ChunkWidth) {

                _pos.Set(x, 0, z); // no y, yet
                _pos.x = Mathf.Floor(_pos.x/ChunkWidth)*ChunkWidth;
                _pos.z = Mathf.Floor(_pos.z/ChunkWidth)*ChunkWidth;

                Chunk chunk = Chunk.FindChunk(_pos);

                // If Chunk is already created, continue
                if (chunk != null)
                    continue;

                // Create a new Chunk..
                chunk = (Chunk) Instantiate(ChunkFab, _pos, Quaternion.identity);
            }
        }
        // Skip to next frame
        yield return 0;
    }
}

Câu trả lời:


1

Những gì bạn cần xem xét tải / tạo một đoạn trên và dưới bề mặt trong bất kỳ ngăn xếp nhất định nào khi trình phát ở trên bề mặt, vì vậy thuật toán thế hệ của bạn cần lo lắng về các ngăn xếp ở cấp cao nhất thay vì khối ... khi trình phát dưới mặt đất một trên và dưới mức chunk hiện tại là tốt. Để làm rõ, một ngăn xếp là một cột dọc của khối từ tầng trệt đến tầng bình lưu :)

Một cách khác để xem xét sẽ là nếu bề mặt nằm dưới cấp độ hiện tại của người chơi - tạo bề mặt và một bên dưới, nếu không thì tạo cấp độ hiện tại và một bên trên và bên dưới.

Vì vậy, giả sử thế giới của bạn sẽ cao 256 khối (* 16 = 4096 khối voxel) và bất cứ lúc nào nếu một ngăn xếp nằm trong phạm vi xem, bạn sẽ có từ 1 đến 3 khối trong ngăn xếp đó thực sự được tải và hiển thị.

Biomes giới thiệu một vấn đề bổ sung về độ cao pha trộn ở các cạnh, nhưng bạn có thể xử lý điều đó trong mã cụ thể của quần xã sẽ được gọi để tạo ra các tính năng bề mặt và dưới bề mặt. Nếu bạn đang sử dụng tiếng ồn perlin / simplex để tạo độ cao, nếu một đoạn giáp với một đoạn là một quần xã khác nhau, bạn có thể nhận được các giá trị nhiễu mà cả hai loại quần xã sẽ tạo ra, sau đó tính trung bình cho chúng.


0

Những gì bạn có thể làm là tạo ra một đoạn 256 cao theo hướng y và chia nó thành 16 phần, mỗi phần cao 16 khối. Sau đó, bạn tạo dữ liệu cho đoạn và xây dựng hình học bên trong các phần.

Một lợi thế sẽ là, bạn có quyền truy cập vào dữ liệu của một đoạn hoàn chỉnh, giúp truy cập dữ liệu trên và dưới một phần dễ dàng hơn.

Điều này cũng có lợi thế là có thể dễ dàng loại bỏ rất nhiều hình học không nằm trong sự thất vọng khi xem. Cũng sẽ có nhiều phần không có bất kỳ hình học nào cả.

Nếu bạn chưa sử dụng nó, tải các đoạn trong một luồng khác cũng có thể cung cấp cho bạn tốc độ khung hình tốt hơn, trong khi tạo dữ liệu cho mỗi khối.


1
Chà, có lẽ tôi đã tự giải thích một chút mơ hồ. Tôi đã có kế hoạch tách một đoạn thành 16 lớp. Nhưng làm thế nào để tôi quyết định tải lớp nào? Mỗi quần xã đều có chiều cao tối thiểu / tối đa của riêng nó. Hãy tưởng tượng Biome A [100,20] Biome B [160,200] - Tôi đang ở rìa của cả hai quần xã. Họ có một sự chuyển tiếp suôn sẻ. Làm thế nào để quyết định tải lớp nào? Nhưng khi viết bài này, tôi nghĩ rằng tôi chỉ cần kiểm tra từng lớp (từ trên xuống dưới) và tạo nó, khi lớp trên trống / trong suốt - và dừng khi lớp đầu tiên được tạo. Hy vọng bạn nhận được điều này;) Thật khó chịu khi bạn không thể thêm các dòng trống trong các bình luận
Brettetete

3
Tôi thấy điểm của bạn. Nhưng nếu bạn thực hiện một thuật toán như chia lưới tham lam, bạn sẽ có thể tải tất cả các lớp mà không làm giảm hiệu suất lớn. Bạn có thể tìm thấy một bài viết về chia lưới tham lam ở đây . Tôi làm tương tự trong động cơ voxel của tôi và nó đang hoạt động tốt cho đến nay.
user000user

Kỹ thuật này chỉ là tuyệt vời. Tôi sẽ cố gắng thực hiện điều này vào động cơ của tôi. Mã đã cho là một chút lạ, bạn sẽ chia sẻ việc thực hiện của bạn? :)
Brettetete

2
Tôi đã dán bản triển khai C ++ của mình vào đây và thêm một số bình luận. Hy vọng rằng sẽ giúp :)
user000user

Tuyệt vời, điều này dường như rất hữu ích. Cảm ơn bạn! Tôi sẽ cố gắng dịch cái này ngay bây giờ. Nhưng trên # 67 - # 68 có một đôi && - bạn có bỏ lỡ / nhân đôi thứ gì đó để sao chép không? :) Và bạn có thể giải thích ngắn gọn / đăng các phương thức SHIFT_ không? Ngoài ra tôi không thấy bất kỳ tuyên bố / sử dụng tmp nào - Chà, sory cho tất cả các câu hỏi đó
Brettetete

0

Tôi không tin rằng bạn có thể làm điều này chỉ bằng cách tải một số lớp nhất định vì vấn đề chuyển đổi.

Xu hướng của tôi sẽ là lưu trữ một số siêu dữ liệu với mỗi đoạn:

1) Là khối hoàn toàn không khí. Nếu vậy thì không cần phải kết xuất nó.

2) Đối với mỗi mặt của khối là mờ đục. Một khuôn mặt mờ đục có nghĩa là bạn không cần phải xem xét phần tiếp theo. (Tuy nhiên, xin lưu ý rằng tùy thuộc vào vị trí của khối có thể có đến ba khuôn mặt liên quan - một đoạn phải được hiển thị nếu bất kỳ trong số ba không bị mờ. Tôi nghi ngờ đây là tính toán tốt nhất - hiển thị quá lâu hoặc b1 có thể nhìn thấy và có mặt không mờ F1 hoặc b2 có thể nhìn thấy có mặt không mờ f2 hoặc b3 có thể nhìn thấy có mặt không mờ f3.)

Thật không may, hơn 7000 khối trong phạm vi tầm nhìn 12 chunk của bạn. Tuy nhiên, tôi hy vọng sẽ có một vài vị trí có nhiều hơn ba khối dọc thực sự cần được hiển thị bằng cách sử dụng phương pháp này để cắt giảm số lượng khối có thể không quá 1500.

Tôi sẽ áp dụng cùng một loại logic trong một đoạn - khi bạn tải một đoạn, hãy tính toán các mối nối nào trong suốt và các mối nối nào mờ đục khi chạm vào - bạn chỉ cần thực sự hiển thị khuôn mặt nơi ai đó có thể nhìn thấy chúng. (Lưu ý rằng trong Minecraft bạn có ba loại khối - trong suốt, mờ đục và thay đổi thị lực - kính, cửa, hàng rào, v.v. Bạn chỉ có thể bỏ qua trong suốt trong suốt và mờ đục.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.