Địa hình mịn Voxel


13

Là một dự án cá nhân, tôi đang cố gắng tạo ra một máy tạo địa hình sẽ tạo ra địa hình trông giống như địa hình trơn tru của Castle Story.

Nếu bạn chưa từng thấy nó ở đây, thì đây: nhập mô tả hình ảnh ở đây

Vì vậy, như bạn có thể thấy, đó là sự kết hợp giữa các khối và khối "trơn tru".

Những gì tôi đã cố gắng làm để mô phỏng diện mạo này là cung cấp cho mỗi khối bề mặt một sơ đồ chiều cao nhỏ. Điều này thường hoạt động, nhưng có một số vấn đề, mang lại một địa hình như thế này:

nhập mô tả hình ảnh ở đây

Vấn đề là mỗi khối có 1x1x1, nhưng đôi khi chiều cao tại một vị trí cụ thể là âm hoặc> 1. Trong trường hợp đó, tôi cắt nó và đặt chiều cao thành 0 hoặc 1.

Để minh họa rõ hơn những gì tôi muốn nói, đây là một sơ đồ: nhập mô tả hình ảnh ở đây

Để tạo chiều cao, về cơ bản tôi làm:

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);
    }
}

Có lẽ tôi đang tiếp cận điều này không chính xác bằng cách sử dụng giá trị nhiễu perlin "thật"?

Mọi sự trợ giúp sẽ rất được trân trọng!

Câu trả lời:


11

Castle Story trông như thế này do các hạn chế kỹ thuật: Đã có một sơ đồ chiều cao cho mỗi voxel trong toàn bộ khối lượng, thay vì chỉ một sơ đồ chiều cao cho mỗi voxel bề mặt , chi phí lưu trữ sẽ lớn hơn rất nhiều, theo thứ tự O (n ^ 3 ) có thể bị cấm, trái ngược với O (n ^ 2) thuận lợi hơn, trong đó n là chiều dài cạnh của không gian voxel hình khối đại diện cho thế giới của bạn. Hãy nhớ rằng thông tin sơ đồ chiều cao cho các voxels dưới mặt đất được ẩn giấu trong cấu trúc lưới, vì vậy thông tin về sơ đồ chiều cao chỉ cần được lưu trữ rõ ràng cho các voxels nằm trên bề mặt. Vì vậy, các anh chàng Castle Story đã chộp các đỉnh vào các kẽ lưới để tiết kiệm chi phí lưu trữ và độ phức tạp của việc xây dựng lưới ... đọc tiếp.

Trước hết, hãy nhìn vào các lựa chọn của bạn:

nhập mô tả hình ảnh ở đây

(1) sẽ gây khó khăn cho bạn, vì trong một cột voxel duy nhất bạn chỉ muốn thông tin sơ đồ chiều cao nhỏ cho voxel trên cùng - hãy xem lại đoạn đầu tiên để biết lý do tại sao. Nhìn vào (1), cột bên phải có thông tin về sơ đồ chiều cao cho cả trên cùng và thứ hai từ trên xuống (và điều này có thể áp dụng cho thứ ba từ trên xuống và cứ thế, nếu độ dốc đủ lớn.). Điều này là không tốt.

(2) Có lẽ là một lựa chọn tốt hơn sau đó; nghĩa là, đảm bảo rằng các đỉnh góc bắt vào các kẽ lưới voxel. Nhưng làm thế nào để chúng ta giải quyết vấn đề độ dốc cực đoan? Chà, chúng ta cần chọn một số gradient trong đó chúng ta chỉ cần chụp vào một cột dọc và do đó đảm bảo rằng chúng ta không có độ dốc hơn có thể cắt ngang qua n voxels trên cùng. Độ dốc 45 độ là ngưỡng tự nhiên vì những lý do tôi giải thích bên dưới. Vì vậy, thay vì (3), chúng tôi sẽ có (4):

nhập mô tả hình ảnh ở đây

(4) Đưa đỉnh góc của voxel vào kẽ lưới gần nhất là giải pháp. Hiệu ứng hình ảnh - răng cưa chéo - có thể được nhìn thấy trong ảnh chụp màn hình Castle Story của bạn. Độ dốc cắt cho các voxels là độ dốc 1: 1, hoặc 45 độ (như được xem trực giao). Làm việc lạc hậu từ giải pháp, chúng ta hãy xem xét các lý do:

  • Cách duy nhất chúng ta có thể có một độ dốc cực lớn, không bị phá vỡ, là nếu một voxel được kéo dài theo chiều dọc ...
  • .... Nhưng không có lưới của voxel có thể vượt quá vùng giới hạn của nó, bất kể hình dạng được làm nhẵn thực sự của nó; một voxel cần phải ngồi trong một không gian xác định trong lưới 3D, nếu không phải là hình thức chính xác, thì ít nhất là đối với hộp giới hạn được căn chỉnh theo trục.

Một lý do khác để tiếp cận nó theo cách này là, như bạn đã phát hiện ra, việc không sử dụng snapping (rời rạc) dẫn đến một loạt các kịch bản làm mịn bề mặt phức tạp về mặt hình học, tốt nhất nên tránh hoàn toàn ... các trò chơi loại này thường không yêu cầu Mức độ chính xác mà thuật toán CSG phù hợp sẽ cung cấp, đó là toàn bộ lý do chúng tôi đang sử dụng voxels ở vị trí đầu tiên: Voxels giúp dễ dàng làm việc tăng dần với các khối lượng, so với thuật toán đa giác / liên kết điểm nổi (liên tục) .


Tôi vừa thử thực hiện điều này, và tôi đã gặp phải một số nhầm lẫn - ý bạn là gì bởi "các kẽ?" Bạn có nghĩa là tọa độ lưới tích phân?
không có tiêu đề

@ThomasBradworth. "Một không gian can thiệp giữa mọi thứ." Đối với 2D, nếu bạn có lưới ô lo lắng, bạn sẽ có (n + 1) x (n + 1) xen kẽ. Điều này mở rộng trực tiếp đến 3D. Chúng là các "đỉnh" liên kết từng ô, phần lớn được chia sẻ giữa nhiều ô / voxels. Nếu bạn đun sôi nó xuống 1D (một dòng) thì nếu cả ô và kẽ được biểu diễn dưới dạng mảng, thì ô 0 được giới hạn bởi kẽ 0 và kẽ 1, trong khi ô 1 được giới hạn bởi kẽ 1 và kẽ 2 ... vv
Kỹ sư

Cảm ơn vi đa trả lơi! Tôi đã cố gắng làm chính xác điều đó, nhưng tôi đã nhận được một số kết quả không thuận lợi. Lúc đầu, tôi đã cố gắng làm tròn các giá trị chiều cao ở các cạnh (khi x là 0 hoặc 4 hoặc z là 0 hoặc 4), nhưng điều đó đã cho tôi: i.imgur.com/eQW7Y.png ( pastebin.com/Lr8vyyHB ) Tiếp theo, tôi đã thử làm mịn các điểm ở giữa, vì vậy tôi đã thêm một "chức năng sửa độ cao": pastebin.com/AazQ07Xm Điều đó, tuy nhiên, cũng cho tôi một kết quả góc cạnh hơn, nhưng cũng tồi tệ hơn: i.imgur.com/q1JVP .png Có lẽ có gì đó không ổn với chức năng tiếng ồn của tôi?
không có tiêu đề

@ThomasBradsworth Đáng buồn thay, tôi cảm thấy bạn chỉ đọc được một nửa / hiểu câu trả lời tôi đã mất hơn một giờ để viết và chỉnh sửa. Quên tiếng ồn; hơn nữa, nếu bạn không hiểu hàm nhiễu, hãy loại bỏ nó khỏi phương trình ngay bây giờ. Vấn đề của bạn nằm ở cách dữ liệu lưới voxel riêng lẻ được tạo ra và nhiễu không liên quan gì đến điều đó, bởi vì bạn có thể tạo một sơ đồ chiều cao trong trường hợp không có nhiễu. Làm việc với trường hợp kiểm tra đơn giản nhất, tức là mã hóa mảng chiều cao. Sau đó xem kết quả của bạn và điều chỉnh thuật toán tạo lưới của bạn. Lặp lại cho đến khi nó làm những gì mong đợi. Sau đó đặt tiếng ồn trở lại, và xem xét.
Kỹ sư

Bạn đang nói rằng tôi chỉ nên lưu trữ các giá trị chiều cao cho các góc và không lưu trữ giá trị chiều cao của các điểm "trung gian"?
không có tiêu đề
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.