Also habe ich mich kürzlich daran versucht und bin auf viele der gleichen Probleme gestoßen, die ihr habt. Die Render-Textur-Lösung ist ein bisschen wie ein roter Hering. Ich konnte es mit Multithreading-Pixel-Manipulation auf einem separaten Thread lösen.
https://www.youtube.com/watch?v=T_zpFk1mdCI
graphics.blit()
Normalerweise verwendet man die Render-Textur und übergibt sie dort, wo sie benötigt wird, aber Lightmap-Daten unterstützen keine Texturen, sondern benötigen texture2ds. Der nächste logische Schritt wäre, die Daten in eine texture2d zu kopieren und diese dann in die Lightmap-Daten einzuspeisen. Diese Technik ruiniert die Bildraten, da die GPU blockiert, um Daten an die CPU zu senden, anstatt nur auf die Daten zu verweisen.
Die Lösung besteht dann darin, die GPU nicht zu verwenden.
Lichtkartenübergänge finden über einen langen Zeitraum statt, sodass es nicht unbedingt wichtig ist, die Lichtkarte bei jedem Frame zu aktualisieren. In der Tat würden die Spieler wahrscheinlich nicht bemerken, wenn die Lichtkarten nur alle 20-40 Minuten in der Spielzeit aktualisiert würden.
Sie geben die Aufgabe also für jede Light Map in separaten Threads an die CPU aus.
Normalerweise unterstützt Unity kein Multithreading. Aber das ist okay, C # tut es. Dieser Typ macht einen phänomenalen Job, um Multithreading in Unity zu erklären. Wenn Sie noch nie davon gehört haben oder noch nie gewusst haben, wie Multithreading in Unity funktioniert, ist dies das Video:
https://www.youtube.com/watch?v=ja63QO1Imck
Sie müssen lediglich eine Arbeitsthreadklasse erstellen, die Kopien der Lightmap-Pixeldaten in Farbarrays variiert, und anschließend eine Mischfunktion erstellen.
Ein einfaches Lerp von einer Farbe zur nächsten reicht aus.
Dann erstelle den Thread, starte ihn und wenn alle Lightmaps in den separaten Threads fertig sind, kannst du die Pixeldaten zurück in die Lightmap-Daten-Textur2d kopieren.
Ich habe unten einen Beispielcode gepostet. Es ist sicherlich nicht die vollständig implementierte Version, aber sie zeigt Ihnen die wichtigsten Konzepte zum Erstellen der Klasse, zum Erstellen des Threads und zum Festlegen der Lichtdaten.
Das andere, was Sie tun müssten, ist, ab und zu eine Funktion aufzurufen, um die Aktualisierung der Lightmaps auszulösen. Außerdem müssen Sie entweder alle Pixeldaten beim Start oder beim Kompilieren in die Worker-Klasse kopieren. Viel Glück für alle, die das finden. Ich glaube, die Operation hat ihr Leben fortgesetzt, aber ich weiß, dass andere Menschen mit ähnlichen Problemen darüber stolpern könnten.
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;
}