Phương pháp hiệu quả kết xuất địa hình lớn trong XNA


10

Tôi đang tạo một trò chơi XNA đòi hỏi một không gian rộng lớn cho người chơi. Hiện tại, sơ đồ chiều cao thử nghiệm tôi đang sử dụng là 4096x4096 và được lưu dưới dạng BMP 4 bit.

Những gì tôi đang cố gắng làm là lấy tập tin heightmap khổng lồ đó và kết xuất nó trong trò chơi. Vấn đề tôi gặp phải là thực tế là không hiệu quả khi tải toàn bộ địa hình vào bộ nhớ cùng một lúc, vì nó sẽ sử dụng phần lớn bộ nhớ khả dụng.

Một vấn đề khác mà tôi gặp phải là tôi không thể hiển thị tất cả địa hình trong một nguyên thủy do có giới hạn cứng được đặt trong XNA.

Như đã nói, tôi đã tìm thấy một số giải pháp, tất cả những giải pháp tôi đã liệt kê dưới đây:

  • Kết xuất dựa trên vị trí của người dùng hiện tại - về cơ bản vẽ một hình vuông xung quanh người dùng bất kể định hướng của họ trên thế giới. Đây không phải là chính xác những gì tôi muốn, bởi vì bạn vẫn hiển thị không gian mà người dùng không nhìn thấy.
  • Kết xuất dựa trên hướng và vị trí của người dùng - Tôi đã tìm thấy một công thức để truy xuất một hình tam giác được cho là có các pixel của sơ đồ chiều cao được cho là được hiển thị, nhưng điều này tỏ ra rất khó khăn.
  • Chia địa hình thành nhiều phần và hiển thị những phần gần nhất với người dùng - Vẫn không hiệu quả lắm vì bạn vẫn hiển thị các phần mà mọi người sẽ không nhìn thấy. Và nó đòi hỏi nhiều công sức vì sau đó tôi phải chia sơ đồ chiều cao của mình thành nhiều phần và khả năng mở rộng trở thành một vấn đề lớn.

Sau khi thử những giải pháp đó, tôi mới biết nên làm gì. Tôi đã nhận được một số câu trả lời nơi mọi người đang bảo tôi thực hiện các thuật toán phức tạp này, nhưng tôi đơn giản là không biết làm thế nào để tiếp cận việc thực hiện chúng.

Vì vậy, về cơ bản, tôi đang yêu cầu một cách đơn giản, đơn giản để hiển thị các địa hình khiêm tốn trong XNA với hiệu quả tối đa.

Tôi còn khá mới mẻ để phát triển trò chơi nói chung, nhưng tôi sẵn sàng nghiên cứu nếu nó có vẻ hứa hẹn.

Cập nhật 1: Sau khi nghiên cứu phương pháp geoclipmapping, tôi bắt đầu viết mã với điều đó. Tôi đã hoàn thành tất cả các phép toán, và trò chơi chạy. Tuy nhiên, nó cực kỳ không hiệu quả - có lẽ là mã hóa xấu về phía tôi. Nó chạy ở 2FPS và sử dụng toàn bộ lõi CPU của tôi. Tôi sẽ thử và cải thiện mã, nhưng tôi nghĩ rằng tôi sẽ cần thêm trợ giúp, vì vậy đây là một Pastebin của mã cho lớp người quản lý địa hình. Tôi sẽ đăng lại với nhiều kết quả hơn sau này nếu tôi thấy nó hiệu quả hơn.


1
Thật thú vị, kỹ thuật mà bạn đang nói đến có vẻ giống với kỹ thuật mà Phần mềm ID đang sử dụng trong trò chơi sắp tới của họ, Rage. Họ sử dụng 'megatexture' và sau đó truyền các phần của nó được yêu cầu vào GPU. Anh ấy đã nói về nó, nhưng đây là một bài viết trên wikipedia, nó có thể truyền cảm hứng: en.wikipedia.org/wiki/MegaTexture

Câu trả lời:


5

Cách tiếp cận chunk thường là những gì được sử dụng. Hiếm khi nó hiệu quả để kiểm tra mỗi tam giác trong số hàng trăm ngàn để xem bạn có nên kết xuất nó không. Thay vào đó, hầu hết các thuật toán kết xuất địa hình sử dụng cấu trúc dữ liệu không gian để tự động kết xuất các phần có thể nhìn thấy của địa hình.

Một cấu trúc dữ liệu dễ thực hiện được gọi là một phần . Nói tóm lại, để sử dụng một góc phần tư, bạn sẽ thấy sự thất vọng khi xem của người chơi, giao nó với mức cao nhất của góc phần tư và đối với bất kỳ khối nào có thể xem được một phần (ví dụ, các mặt phẳng bực bội giao nhau) bạn chia nhỏ và kiểm tra tất cả trẻ em khối, bỏ qua những người bên ngoài sự thất vọng. Điều này sẽ đưa ra một xấp xỉ khá gần với hình học có thể nhìn thấy thực tế chỉ với một vài mức đệ quy.

Trình kết xuất địa hình nâng cao hơn sử dụng thuật toán để điều chỉnh không chỉ hình học có thể xem mà cả chi tiết của hình học đó. Geomipmapping (và geoclipmapping tương đối của nó) hiện tại tương đối phổ biến để làm điều đó nhưng không phải là một việc nhỏ để thực hiện.

chỉnh sửa: Dưới đây là một mô tả đúng đắn về cả geoclipmapping và sự loại bỏ bực bội.

Tôi cũng có một số nghi ngờ về việc liệu 4 bit cho sơ đồ chiều cao có thực sự đủ để tạo ra một địa hình có giao diện đẹp hay không, trừ khi bạn đang làm rất nhiều kết quả.


Tôi đã xem bài báo đó và tôi đã quyết định rằng tôi sẽ sử dụng phương pháp lập bản đồ địa lý trước, vì có vẻ như nó sẽ hiệu quả nhất trong việc hiển thị một lượng lớn địa hình. Tôi sẽ gửi lại với kết quả của tôi.

3

Bất kỳ phương pháp nào yêu cầu bạn thực hiện công việc trên mỗi khung hình để tải dữ liệu lên GPU sẽ bị thiếu sót.

Đây là một phác thảo sơ bộ về một cách tiếp cận sẽ thực hiện tốt:

Bạn nên chia địa hình của mình thành các khối (khá lớn), tải các khối đó vào bộ đệm đỉnh cố định (độ sâu bit của bản đồ chiều cao của bạn không thành vấn đề!). Những bộ đệm đỉnh đó sẽ chỉ đơn giản là ngồi trong bộ nhớ GPU, chờ kết xuất. Bạn sẽ phải thử nghiệm kích thước khối phù hợp là gì, nhưng 128x128 có lẽ là một nơi tốt để bắt đầu.

Đối với địa hình 4096x4096, bạn hơi vượt quá giới hạn của việc tải thoải mái vào GPU cùng một lúc - có thể là vài trăm MB dữ liệu đỉnh (mặc dù bạn có thể giảm xuống ~ 64 MB nếu bạn tài giỏi). Vì vậy, bạn có thể phải tải và dỡ bộ đệm đỉnh từ GPU trong nền.

(Nếu bạn thực hiện tải nền của khối, điều này sẽ cực kỳ có thể mở rộng!)

Sau khi bạn có dữ liệu đỉnh trên GPU, đây là thời điểm thích hợp để loại bỏ khả năng hiển thị trên cơ sở mỗi khối . Không cần phải gửi lệnh để kết xuất một đoạn, nếu bạn biết nó nằm phía sau camera.

Bạn gần như không bao giờ được thực hiện loại bỏ tam giác trên CPU!

GPU sẽ tiêu hủy tam giác đó là tắt màn hình nhiều nhanh hơn bạn sẽ không bao giờ có thể.

Để biết thêm thông tin về hiệu suất, hãy xem câu trả lời này trên trang web Game Dev.


0

Tôi không phải là một chuyên gia tại XNA, vì vậy xin vui lòng sửa lỗi cho tôi nếu tôi sai nhưng tôi có ấn tượng rằng thực sự được xây dựng để tối ưu hóa cho các tình huống như thế này. Tôi biết bạn có thể đặt khoảng cách kết xuất và sau thời điểm đó, nó không hiển thị bất cứ thứ gì, trong trường hợp của bạn, đó sẽ là địa hình còn lại. Tuy nhiên, điều này để lại một khía cạnh khá kém hấp dẫn đối với thế giới được hiển thị của bạn, vì vậy bạn sẽ phải thực hiện một cái gì đó giống như sương mù mà hầu hết các trò chơi thế giới mở đều có.


Có các giải pháp được xây dựng, nhưng vấn đề tôi gặp phải là tôi đang cố gắng hiển thị một nguyên thủy lớn, vượt quá giới hạn về đa giác cho các nguyên thủy. Vì vậy, nó sẽ không rút ra, chỉ cần ném một ngoại lệ.
lấy mẫu vào
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.