Quindi di recente ho provato a farlo e ho riscontrato molti degli stessi problemi che voi ragazzi avete. La soluzione di texture di rendering è un po 'un'aringa rossa. Sono stato in grado di risolverlo usando la manipolazione di pixel multithreading su un thread separato.
https://www.youtube.com/watch?v=T_zpFk1mdCI
Quindi di solito si userebbe graphics.blit()
e passerebbe la trama di rendering dove deve andare, ma i dati di lightmap non supportano le trame, richiedono texture2ds. Il prossimo passo logico sarebbe quello di copiare i dati in una texture2d e quindi di inviarli ai dati della mappa luminosa. Questa tecnica rovina i frame rate perché sta bloccando la GPU per inviare dati alla CPU, piuttosto che solo un riferimento ai dati.
La soluzione è quindi di non utilizzare la GPU.
Le transizioni della mappa di luce avvengono per un lungo periodo di tempo, quindi non è necessariamente importante aggiornare la mappa di luce ogni fotogramma. È un dato di fatto, i giocatori probabilmente non noterebbero se le mappe luminose fossero aggiornate solo ogni 20-40 minuti nel tempo di gioco.
Quindi, ciò che fai è inviare l'attività alla CPU su thread separati per ogni mappa luminosa.
Normalmente Unity non supporta il multithreading. Ma va bene, C # lo fa. Questo ragazzo fa un lavoro fenomenale spiegando il multithreading in Unity, quindi se non ne hai mai sentito parlare o non hai mai saputo come fare il multithread in Unity questo è il video:
https://www.youtube.com/watch?v=ja63QO1Imck
Tutto quello che devi fare è creare una classe di thread di lavoro che vari le copie dei dati dei pixel della mappa luminosa negli array Color e quindi creare una funzione di fusione.
Sarà sufficiente un semplice passaggio da un colore all'altro.
Quindi creare il thread, avviarlo e quando tutte le mappe luminose sono terminate in thread separati è possibile copiare nuovamente i dati dei pixel nella texture2d dei dati della mappa luminosa.
Ho pubblicato un codice di esempio di seguito. Non è certamente la versione completamente implementata, ma ti mostra i concetti principali di come creare la classe, creare il thread e quindi impostare i dati di luce.
L'altra cosa che dovresti fare è chiamare una funzione ogni tanto per attivare l'aggiornamento delle mappe luminose. Inoltre, è necessario copiare tutti i dati pixel nella classe lavoratore all'avvio o al momento della compilazione. Buona fortuna a chiunque lo trovi. Immagino che l'operazione sia andata avanti con la loro vita, ma so che altre persone con problemi simili potrebbero inciampare in questo.
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;
}