Bu yüzden son zamanlarda elimi bu konuda denedim ve sahip olduğunuz birçok sorunla karşılaştım. Render doku çözümü biraz kırmızı ringa balığıdır. Ayrı bir iş parçacığındaki multithreading piksel manipülasyon kullanarak çözmeyi başardı.
https://www.youtube.com/watch?v=T_zpFk1mdCI
Bu nedenle, normalde graphics.blit()
render dokusunu gitmesi gereken her yere kullanır ve geçirir, ancak ışık haritası verileri dokuları desteklemez, texture2ds gerektirir. Bir sonraki mantıksal adım, verilerin bir texture2d dosyasına kopyalanması ve ardından ışık haritası verilerine beslenmesi olacaktır. Bu teknik kare hızlarını bozar, çünkü GPU'yu yalnızca verilere referans olmaktan ziyade CPU'ya veri göndermek için durdurur.
Çözüm GPU'yu kullanmamaktır.
Işık haritası geçişleri uzun bir süre boyunca gerçekleşir, bu nedenle ışık haritasını her karede güncellemek önemli değildir. Aslında, oyuncular ışık haritalarının oyun süresinde sadece 20-40 dakikada bir güncellenip güncellenmediğini fark etmeyeceklerdir.
Yaptığınız şey, görevi her ışık haritası için ayrı iş parçacıkları üzerinde CPU'ya vermektir.
Normalde Unity, çoklu iş parçacığı kullanımını desteklemez. Ama sorun değil, C #. Bu adam Unity'de çoklu iş parçacığını açıklayan olağanüstü bir iş yapar, bu yüzden daha önce hiç duymadıysanız veya Unity'de çok iş parçacığının nasıl kullanılacağını hiç bilmiyorsanız bu video:
https://www.youtube.com/watch?v=ja63QO1Imck
Tek yapmanız gereken Renk dizilerindeki ışık haritası piksel verilerinin kopyalarını değiştiren bir işçi iş parçacığı sınıfı yapmak ve ardından bir karışım işlevi oluşturmaktır.
Bir renkten diğerine basit bir lerp yapacaktır.
Ardından iş parçacığını oluşturun, başlatın ve tüm ışık eşlemeleri ayrı iş parçacıklarında tamamlandığında piksel verilerini tekrar ışık haritası veri texture2d'sine kopyalayabilirsiniz.
Aşağıda bazı örnek kodlar yayınladım. Kesinlikle tam olarak uygulanmış sürüm değildir, ancak sınıfın yapılması, iş parçacığının oluşturulması ve ardından ışık verilerinin ayarlanmasıyla ilgili temel kavramları gösterir.
Yapmanız gereken diğer şeyler, ışık haritalarının güncellenmesini tetiklemek için sık sık bir işlev çağırmaktır. Ayrıca, tüm piksel verilerini başlangıçta veya derleme zamanında işçi sınıfına kopyalamanız gerekir. Bunu bulan herkese iyi şanslar. Operasyonun hayatları boyunca ilerlediğini düşünüyorum, ancak benzer sorunları olan diğer insanların bununla karşılaşabileceğini biliyorum.
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;
}