Trước đây tôi đã thực hiện diễu hành khối / tứ diện để hiển thị IsoSurface. Nó đã hoạt động ( YouTube ), nhưng hiệu suất rất tệ vì tôi chưa bao giờ thực hiện Cấp độ chi tiết thay đổi dựa trên khoảng cách xem (hoặc thậm chí loại bỏ các đoạn cũ, xa).
Tôi quyết định có một lần đi khác và làm điều đó đúng cách lần này. Tôi đã bắt đầu bằng cách tạo OctreeNode hoạt động như sau khi Build()
được gọi.
- Nếu chunk quá nhỏ để xây dựng, trở lại ngay lập tức.
- Làm việc nếu bề mặt đi qua khối lượng của khối này.
- Nếu vậy, sau đó quyết định xem chúng tôi có muốn tăng LOD không (vì máy ảnh đã đóng)
- Nếu vậy, sau đó sinh ra 8 đứa trẻ và gọi quá trình tương tự trên chúng
- Nếu không, xây dựng lưới bằng kích thước của nút hiện tại
Một số mã giả:
OctNode Build() {
if(this.ChunkSize < minChunkSize) {
return null;
}
densityRange = densitySource¹.GetDensityRange(this.bounds);
if(densityRange.min < surface < densityRange.max) {
if(loDProvider.DesiredLod(bounds)² > currentLoD) {
for(i 1 to 8) {
if(children[i] == null) {
children[i] = new OctNode(...)
}
children[i] = children[i].Build();
}
} else {
BuildMesh();
}
return this;
}
}
Cũng như trả về mật độ tại một điểm, nguồn mật độ có thể xác định phạm vi mật độ có thể có cho một khối lượng nhất định.
² Nhà cung cấp LoD lấy một hộp giới hạn và trả về LoD tối đa mong muốn dựa trên vị trí / sự thất vọng của máy ảnh, cài đặt người dùng, v.v ...
Vì vậy, ... Tất cả điều này hoạt động khá tốt. Sử dụng một hình cầu đơn giản làm nguồn Mật độ và hiển thị tất cả các nút:
Và chỉ những chiếc lá:
Tuy nhiên, có một vài vấn đề:
- Tôi phải xác định khối lượng giới hạn ban đầu (và nó càng lớn thì tôi càng phải xử lý nhiều hơn)
- Ở phần gốc của cây, tôi không biết lá sẽ sâu đến mức nào, vì vậy việc đánh số LoD của tôi bắt đầu ở chất lượng thấp nhất (gốc) và tăng lên khi các khối nhỏ hơn. Vì LoD hiện tại có liên quan đến khối lượng ban đầu, nên tôi không sử dụng nhiều khi tôi muốn làm mọi thứ ở kích cỡ / chất lượng cụ thể.
Tôi đã nghĩ đến một vài lựa chọn nhưng cả hai đều có vẻ thiếu sót:
- Duy trì một bộ sưu tập Octrees và thêm / xóa tùy theo khoảng cách. Không thể thấy cách tôi chia lưới một cách độc đáo¹, cộng với tôi cần một danh sách các nút trống đã biết, đặc biệt là nếu tôi muốn các bề mặt 3D tùy ý (để tránh tính toán lại các khối lượng trống liên tục)
- Thêm một nút cha mẹ vào gốc hiện tại, sau đó thêm bảy anh chị em cho nút ban đầu. Điều này sẽ hoạt động và theo yêu cầu nhưng có vẻ phức tạp để thu nhỏ lại một cách hợp lý khi người chơi di chuyển qua phong cảnh. Nó cũng sẽ làm cho số LoD thậm chí ít ý nghĩa hơn.
¹ [Để làm rõ Q bên dưới] Hiện tại, nếu 2 nút liền kề vật lý trong cây ở các LOD khác nhau, tôi có một số mã để ép buộc các câu sao cho không có đường nối khi các lưới được tạo. Tôi có thể làm điều này bằng cách biết mật độ cho nhiều nút xung quanh. Trong trường hợp tôi có 2 quãng tám độc lập cạnh nhau, tôi không có cách nào dễ dàng để lấy thông tin này, dẫn đến các đường nối.
Cách tối ưu để tiếp cận điều này là gì?