Tôi đang viết bản sao Minecraft của riêng mình (cũng được viết bằng Java). Nó hoạt động tuyệt vời ngay bây giờ. Với khoảng cách xem 40 mét, tôi có thể dễ dàng đạt 60 FPS trên MacBook Pro 8.1. (Intel i5 + Intel HD Graphics 3000). Nhưng nếu tôi đặt khoảng cách xem trên 70 mét, tôi chỉ đạt 15-25 FPS. Trong Minecraft thực, tôi có thể đặt khoảng cách xem ở xa (= 256m) mà không gặp vấn đề gì. Vì vậy, câu hỏi của tôi là tôi nên làm gì để làm cho trò chơi của tôi tốt hơn?
Những tối ưu hóa tôi đã thực hiện:
- Chỉ giữ các khối cục bộ trong bộ nhớ (tùy thuộc vào khoảng cách xem của người chơi)
- Frustum culling (Đầu tiên trên các khối, sau đó trên các khối)
- Chỉ vẽ các mặt thực sự có thể nhìn thấy của các khối
- Sử dụng danh sách trên mỗi đoạn có chứa các khối có thể nhìn thấy. Chunks trở nên hữu hình sẽ thêm chính nó vào danh sách này. Nếu chúng trở nên vô hình, chúng sẽ tự động bị xóa khỏi danh sách này. Các khối trở nên (trong) có thể nhìn thấy bằng cách xây dựng hoặc phá hủy một khối lân cận.
- Sử dụng danh sách trên mỗi đoạn có chứa các khối cập nhật. Cơ chế tương tự như danh sách khối có thể nhìn thấy.
- Sử dụng gần như không có
new
tuyên bố trong vòng lặp trò chơi. (Trò chơi của tôi chạy khoảng 20 giây cho đến khi Trình thu gom rác được gọi) - Hiện tại tôi đang sử dụng danh sách cuộc gọi OpenGL. (
glNewList()
,glEndList()
,glCallList()
) Cho mỗi bên của một loại khối.
Hiện tại tôi thậm chí không sử dụng bất kỳ loại hệ thống chiếu sáng. Tôi đã nghe nói về VBO. Nhưng tôi không biết chính xác nó là gì. Tuy nhiên, tôi sẽ làm một số nghiên cứu về chúng. Họ sẽ cải thiện hiệu suất? Trước khi triển khai VBO, tôi muốn thử sử dụng glCallLists()
và vượt qua danh sách danh sách cuộc gọi. Thay vì sử dụng ngàn lần glCallList()
. (Tôi muốn thử điều này, vì tôi nghĩ rằng MineCraft thực sự không sử dụng VBO. Đúng không?)
Có những thủ thuật khác để cải thiện hiệu suất?
Cấu hình VisualVM cho tôi thấy điều này (chỉ lược tả 33 khung hình, với khoảng cách xem là 70 mét):
Hồ sơ với 40 mét (246 khung):
Lưu ý: Tôi đang đồng bộ hóa rất nhiều phương thức và khối mã, bởi vì tôi đang tạo các khối trong một luồng khác. Tôi nghĩ rằng việc có được một khóa cho một đối tượng là một vấn đề hiệu năng khi thực hiện nhiều điều này trong một vòng lặp trò chơi (tất nhiên, tôi đang nói về thời gian khi chỉ có vòng lặp trò chơi và không có đoạn mới nào được tạo ra). Thê nay đung không?
Chỉnh sửa: Sau khi loại bỏ một số synchronised
khối và một số cải tiến nhỏ khác. Hiệu suất đã tốt hơn nhiều. Dưới đây là kết quả hồ sơ mới của tôi với 70 mét:
Tôi nghĩ rằng nó là khá rõ ràng đó selectVisibleBlocks
là vấn đề ở đây.
Cảm ơn trước!
Martijn
Cập nhật : Sau một số cải tiến bổ sung (như sử dụng các vòng lặp thay cho từng vòng, đệm các biến bên ngoài các vòng lặp, v.v ...), giờ đây tôi có thể chạy khoảng cách xem 60 khá tốt.
Tôi nghĩ rằng tôi sẽ triển khai VBO càng sớm càng tốt.
PS: Tất cả mã nguồn có sẵn trên GitHub:
https://github.com/mcourteaux/CraftMania