Tôi đang sử dụng C # và XNA. Thuật toán hiện tại của tôi cho ánh sáng là một phương pháp đệ quy. Tuy nhiên, nó rất tốn kém , đến mức mà một đoạn 8x128x8 được tính cứ sau 5 giây.
- Có phương pháp chiếu sáng nào khác sẽ tạo ra bóng tối thay đổi không?
- Hoặc là phương pháp đệ quy tốt, và có lẽ tôi chỉ đang làm sai?
Có vẻ như các công cụ đệ quy rất tốn kém về cơ bản (buộc phải trải qua khoảng 25 nghìn khối mỗi khối). Tôi đã suy nghĩ về việc sử dụng một phương pháp tương tự như phương pháp dò tia, nhưng tôi không biết làm thế nào nó sẽ hoạt động. Một điều khác tôi đã thử là lưu trữ các nguồn sáng trong Danh sách và cho mỗi khối có khoảng cách đến từng nguồn sáng và sử dụng nó để chiếu sáng đến mức chính xác, nhưng sau đó ánh sáng sẽ đi qua các bức tường.
Mã đệ quy hiện tại của tôi là dưới đây. Điều này được gọi từ bất kỳ nơi nào trong khối không có mức độ ánh sáng bằng 0, sau khi xóa và thêm lại ánh sáng mặt trời và đèn pin.
world.get___at
là một hàm có thể lấy các khối bên ngoài khối này (đây là bên trong lớp chunk). Location
là cấu trúc của riêng tôi giống như một Vector3
, nhưng sử dụng các số nguyên thay vì các giá trị dấu phẩy động. light[,,]
là ánh sáng cho chunk.
private void recursiveLight(int x, int y, int z, byte lightLevel)
{
Location loc = new Location(x + chunkx * 8, y, z + chunky * 8);
if (world.getBlockAt(loc).BlockData.isSolid)
return;
lightLevel--;
if (world.getLightAt(loc) >= lightLevel || lightLevel <= 0)
return;
if (y < 0 || y > 127 || x < -8 || x > 16 || z < -8 || z > 16)
return;
if (x >= 0 && x < 8 && z >= 0 && z < 8)
light[x, y, z] = lightLevel;
recursiveLight(x + 1, y, z, lightLevel);
recursiveLight(x - 1, y, z, lightLevel);
recursiveLight(x, y + 1, z, lightLevel);
recursiveLight(x, y - 1, z, lightLevel);
recursiveLight(x, y, z + 1, lightLevel);
recursiveLight(x, y, z - 1, lightLevel);
}