So I recently tried my hand at this and ran into a lot of the same issues you guys have. The render texture solution is a bit of a red herring. I was able to solve it using multithreading pixel manipulation on a separate thread.
https://www.youtube.com/watch?v=T_zpFk1mdCI
So ordinarily one would use graphics.blit()
and pass the render texture in to wherever it needs to go, but lightmap data doesn't support textures, they require texture2ds. The next logical step would be to copy the data to a texture2d and then feed that to the lightmap data. This technique ruins frame rates because it is stalling the GPU to send data to the CPU, rather than just a reference to the data.
The solution is then to not use the GPU.
Light map transitions happen over a long period of time so it is not necessarily important to update the light map every frame. As a matter of fact, players probably wouldn't notice if the light maps were only updated every 20-40 minutes in game time.
So what you do is you issue the task out to the CPU on separate threads for each light map.
Ordinarily Unity does not support multithreading. But that's okay, C# does.
This guy does a phenomenal job explain multithreading in Unity, so if you've never heard of it, or never knew how to multithread in Unity this is the video:
https://www.youtube.com/watch?v=ja63QO1Imck
All you need to do is make a worker thread class that varies copies of the lightmap pixel data in Color arrays, and then create a blend function.
A simple lerp from one color to the next will do.
Then create the thread, start it, and when all the lightmaps are finished in the separate threads you can copy the pixel data back into the lightmap data texture2d.
I posted some example code below. It's certainly not the fully implemented version, but it shows you the main concepts of making the class, creating the thread, and then setting the lightdata.
The other things you would have to do is call a function every so often to trigger updating the lightmaps. Also you have to either copy all of the pixel data into the worker class at start or at compile time. Good luck to anyone who finds this. I figure the op has moved on with their life, but I know other people with similar problems might stumble upon this.
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;
}
Graphics.Blit()
to render it? I've never done this, but looking in the manual, it should work. \$\endgroup\$