Vì vậy, gần đây tôi đã thử điều này và gặp rất nhiều vấn đề tương tự như các bạn có. Các giải pháp kết cấu kết xuất là một chút cá trích đỏ. Tôi đã có thể giải quyết nó bằng cách sử dụng thao tác pixel đa luồng trên một luồng riêng biệt.
https://www.youtube.com/watch?v=T_zpFk1mdCI
Vì vậy, thông thường người ta sẽ sử dụng graphics.blit()
và chuyển kết cấu kết xuất đến bất cứ nơi nào nó cần đến, nhưng dữ liệu lightmap không hỗ trợ kết cấu, chúng yêu cầu texture2ds. Bước hợp lý tiếp theo sẽ là sao chép dữ liệu vào texture2d và sau đó đưa dữ liệu đó vào dữ liệu lightmap. Kỹ thuật này phá hỏng tốc độ khung hình vì nó đang cản trở GPU gửi dữ liệu tới CPU, thay vì chỉ tham chiếu đến dữ liệu.
Giải pháp là sau đó không sử dụng GPU.
Quá trình chuyển đổi bản đồ ánh sáng diễn ra trong một khoảng thời gian dài, do đó không nhất thiết phải cập nhật bản đồ ánh sáng mỗi khung hình. Thực tế, người chơi có thể sẽ không chú ý nếu bản đồ ánh sáng chỉ được cập nhật cứ sau 20 - 40 phút trong thời gian trò chơi.
Vì vậy, những gì bạn làm là bạn đưa ra nhiệm vụ cho CPU trên các luồng riêng biệt cho mỗi bản đồ ánh sáng.
Thông thường Unity không hỗ trợ đa luồng. Nhưng không sao, C # thì có. Anh chàng này thực hiện một công việc phi thường giải thích đa luồng trong Unity, vì vậy nếu bạn chưa bao giờ nghe về nó, hoặc chưa bao giờ biết cách đa luồng trong Unity thì đây là video:
https://www.youtube.com/watch?v=ja63QO1Imck
Tất cả những gì bạn cần làm là tạo một lớp luồng công nhân thay đổi các bản sao của dữ liệu pixel ánh sáng trong mảng Màu, sau đó tạo một hàm pha trộn.
Một lerp đơn giản từ màu này sang màu tiếp theo sẽ làm.
Sau đó tạo luồng, khởi động nó và khi tất cả các ánh sáng kết thúc trong các luồng riêng biệt, bạn có thể sao chép dữ liệu pixel trở lại vào data2d của lightmap data2d.
Tôi đã đăng một số mã ví dụ dưới đây. Đây chắc chắn không phải là phiên bản được triển khai đầy đủ, nhưng nó cho bạn thấy các khái niệm chính về việc tạo lớp, tạo luồng và sau đó thiết lập lightdata.
Những việc khác bạn sẽ phải làm là thường xuyên gọi một chức năng để kích hoạt cập nhật các bản đồ ánh sáng. Ngoài ra, bạn phải sao chép tất cả dữ liệu pixel vào lớp worker khi bắt đầu hoặc tại thời điểm biên dịch. Chúc may mắn cho bất cứ ai tìm thấy điều này. Tôi nghĩ rằng op đã tiếp tục cuộc sống của họ, nhưng tôi biết những người khác có vấn đề tương tự có thể vấp phải điều này.
public class work
{
Color[] fromPixels;
Color[] toPixels;
public float LerpValue = 0;
public bool Finished = false;
public Color[] mixedPixels;
public work(Color[] FromPix, Color[] ToPix)
{
fromPixels= FromPix;
toPixels= ToPix;
Finished = false;
mixedPixels = new Color[FromPix.Length];
}
public void DoWork()
{
for (int x = 0; x < fromPixels.Length; x++)
{
mixedPixels[x] = Color.Lerp(fromPixels[x], toPixels[x], LerpValue);
}
Finished = true;
}
}
IEnumerator LightMapSet()
{
Thread workerThread = new Thread(someworker.DoWork);
someworker.LerpValue = lerpValue;
workerThread.Start();
yield return new WaitUntil(() => someworker.Finished);
mixedMap.SetPixels(someworker.mixedPixels);
mixedMap.Apply(true);
LightmapData someLightmapData;
someLightmapData.lightmapColor = mixedMap;
lightDatas = { someLightmapData};
LightmapSettings.lightmaps = lightDatas;
}