Niedawno więc spróbowałem swoich sił i napotkałem wiele takich samych problemów, jakie macie. Rozwiązaniem do renderowania tekstury jest trochę czerwony śledź. Udało mi się to rozwiązać za pomocą wielowątkowej manipulacji pikselami w osobnym wątku.
https://www.youtube.com/watch?v=T_zpFk1mdCI
Zwykle używa się graphics.blit()
i przekazuje teksturę renderowania tam, gdzie trzeba, ale dane lightmap nie obsługują tekstur, wymagają texture2ds. Kolejnym logicznym krokiem byłoby skopiowanie danych do texture2d, a następnie przekazanie ich do danych lightmap. Ta technika rujnuje liczbę klatek na sekundę, ponieważ opóźnia procesor graficzny, aby wysłać dane do procesora, a nie tylko odniesienie do danych.
Rozwiązaniem jest wtedy, aby nie używać GPU.
Przejścia jasnej mapy następują przez długi czas, więc aktualizowanie jasnej mapy co klatkę nie musi być ważne. W rzeczywistości gracze prawdopodobnie nie zauważyliby, gdyby lekkie mapy były aktualizowane tylko co 20-40 minut w czasie gry.
Więc to, co robisz, wysyłasz zadanie do CPU osobnymi wątkami dla każdej mapy świetlnej.
Zwykle jedność nie obsługuje wielowątkowości. Ale to dobrze, C # robi. Ten facet wykonuje fenomenalną robotę wyjaśniając wielowątkowość w Unity, więc jeśli nigdy o tym nie słyszałeś lub nigdy nie wiedziałeś, jak wielowątkowość w Unity to ten film:
https://www.youtube.com/watch?v=ja63QO1Imck
Wszystko, co musisz zrobić, to utworzyć roboczą klasę wątków, która zmienia kopie danych pikseli lightmap w tablicach kolorów, a następnie utworzyć funkcję mieszania.
Wystarczy prosty lerp z jednego koloru do drugiego.
Następnie utwórz wątek, uruchom go, a gdy wszystkie lightmapy zostaną ukończone w osobnych wątkach, możesz skopiować dane pikseli z powrotem do danych lightmap texture2d.
Poniżej zamieściłem przykładowy kod. Z pewnością nie jest to w pełni zaimplementowana wersja, ale pokazuje główne koncepcje tworzenia klasy, tworzenia wątku, a następnie ustawiania lightdata.
Inną rzeczą, którą musisz zrobić, to wywoływać funkcję co jakiś czas, aby uruchomić aktualizację map świetlnych. Musisz także skopiować wszystkie dane pikseli do klasy procesu roboczego na początku lub w czasie kompilacji. Powodzenia dla każdego, kto to znajdzie. Myślę, że operacja przeszła z ich życiem, ale wiem, że inni ludzie z podobnymi problemami mogą się na to natknąć.
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;
}