Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Problems with instantiating baked prefabs

Discussion in 'Global Illumination' started by GSdev, May 8, 2015.

Thread Status:
Not open for further replies.
  1. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    Thanks for your work....I would like to know if Unity is going to fix current problem or its given that we have to go through scripts you developed?
     
  2. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    They have a lot on they're plate and I think procedural levels has never really been a top focus for the Unity team. I could be wrong, but I wouldn't expect a solution soon.
     
    idurvesh likes this.
  3. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
  4. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    I have not tried the code with LOD yet. How're you implementing your LOD? Are you using Unity's built-in LOD support or are you using a custom solution?
     
  5. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    We are plan to add it in couple of days..There are two options for us, QuickLOD from asset store or Unity's built in ....Our priority was whichever does fast job we will implement it, though now it seems like whichever implements LOD with prefabs lightmap we will go for it...
     
  6. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    Do you have your LOD levels in one asset file or are you using something to create the LOD level? I believe QuickLOD is just a LOD manager, I do not believe create the LOD levels. I could be wrong. But I do not see any mention of polygon reduction nor texture atlasing.
     
    idurvesh likes this.
  7. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    I haven't tested it yet, but if you're LOD are separate asset game objects which seems to be the case for most assets on the Asset Store, then you need to make sure all the detail levels except LOD0 are inactive. Then do your prefab lightmapping. After that you can copy the PrefabLightmapData component and it's values to the other LOD levels. Make sure you only have one PrefabLightmapData component instance per LOD level. If your load levels are under are GameObjects under a root GameObject, you need to have PrefabLightmapData script on each LOD level and not the root GameObject
     
    idurvesh likes this.
  8. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    Thanks for replay, I have made some changes to script and created "Assign lightmaps to LOD" exec in Asset's menu.

    Here is code,
    Code (CSharp):
    1. #if UNITY_EDITOR
    2. using UnityEditor;
    3. #endif
    4. using UnityEngine;
    5. using System.Collections.Generic;
    6. using System.Linq;
    7.  
    8.  
    9. public class PrefabLightmapData : MonoBehaviour
    10. {
    11.     [System.Serializable]
    12.     struct RendererInfo
    13.     {
    14.         public List <Renderer> renderer;
    15.         public int lightmapIndex;
    16.         public Vector4 lightmapOffsetScale;
    17.     }
    18.  
    19.     [SerializeField]
    20.   List<RendererInfo> m_RendererInfo;
    21.     [SerializeField]
    22.     Texture2D[] m_Lightmaps;
    23.     [SerializeField]
    24.     Texture2D[] m_Lightmaps2;
    25.  
    26.     const string LIGHTMAP_RESOURCE_PATH = "Assets/Resources/Lightmaps/";
    27.  
    28.  
    29.  
    30.     [System.Serializable]
    31.     struct Texture2D_Remap
    32.     {
    33.         public int originalLightmapIndex;
    34.         public Texture2D originalLightmap;
    35.         public Texture2D lightmap;
    36.         public Texture2D lightmap2;
    37.     }
    38.  
    39.     static List<Texture2D_Remap> sceneLightmaps = new List<Texture2D_Remap>();
    40.  
    41.     void Awake()
    42.     {
    43.         ApplyLightmaps(m_RendererInfo, m_Lightmaps, m_Lightmaps2);
    44.     }
    45.  
    46.     static void ApplyLightmaps( List <RendererInfo> rendererInfo, Texture2D[] lightmaps, Texture2D[] lightmaps2)
    47.     {
    48.         bool existsAlready = false;
    49.         int counter = 0;
    50.         int[] lightmapArrayOffsetIndex;
    51.  
    52.         if (rendererInfo == null || rendererInfo.Count == 0)
    53.             return;
    54.  
    55.         var settingslightmaps = LightmapSettings.lightmaps;
    56.         var combinedLightmaps = new List<LightmapData>();
    57.         lightmapArrayOffsetIndex = new int[lightmaps.Length];
    58.  
    59.         for (int i = 0; i < lightmaps.Length; i++)
    60.         {
    61.             existsAlready = false;
    62.             for (int j = 0; j < settingslightmaps.Length; j++)
    63.             {
    64.                 if (lightmaps[i] == settingslightmaps[j].lightmapFar)
    65.                 {
    66.                     lightmapArrayOffsetIndex[i] = j;
    67.                     existsAlready = true;
    68.                 }
    69.             }
    70.  
    71.             if (!existsAlready)
    72.             {
    73.                 lightmapArrayOffsetIndex[i] = counter + settingslightmaps.Length;
    74.                 var newLightmapData = new LightmapData();
    75.                 newLightmapData.lightmapFar = lightmaps[i];
    76.                 newLightmapData.lightmapNear = lightmaps2[i];
    77.                 combinedLightmaps.Add(newLightmapData);
    78.                 ++counter;
    79.             }
    80.         }
    81.  
    82.         var combinedLightmaps2 = new LightmapData[settingslightmaps.Length + counter];
    83.         settingslightmaps.CopyTo(combinedLightmaps2, 0);
    84.  
    85.         if (counter > 0)
    86.         {
    87.             for (int i = 0; i < combinedLightmaps.Count; i++)
    88.             {
    89.                 combinedLightmaps2[i + settingslightmaps.Length] = new LightmapData();
    90.                 combinedLightmaps2[i + settingslightmaps.Length].lightmapFar = combinedLightmaps[i].lightmapFar;
    91.                 combinedLightmaps2[i + settingslightmaps.Length].lightmapNear = combinedLightmaps[i].lightmapNear;
    92.             }
    93.         }
    94.  
    95.         ApplyRendererInfo(rendererInfo, lightmapArrayOffsetIndex);
    96.  
    97.         LightmapSettings.lightmaps = combinedLightmaps2;
    98.     }
    99.  
    100.     static void ApplyRendererInfo(List<RendererInfo> infos, int[] arrayOffsetIndex)
    101.     {
    102.         for (int i = 0; i < infos.Count; i++)
    103.         {
    104.             var info = infos[i];
    105.             foreach (Renderer rer in info.renderer)
    106.             {
    107.                 rer.lightmapIndex = arrayOffsetIndex[info.lightmapIndex];
    108.                 rer.lightmapScaleOffset = info.lightmapOffsetScale;
    109.             }
    110.         }
    111.     }
    112.  
    113. #if UNITY_EDITOR
    114.  
    115.     [MenuItem("Assets/Add lightmap to LOD")]
    116.     static void UseMeBeforeUpdatint()
    117.     {
    118.  
    119.         PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
    120.  
    121.         foreach (var instance in prefabs)
    122.         {
    123.  
    124.             foreach(RendererInfo ren in instance.m_RendererInfo) {
    125.  
    126.  
    127.                 foreach(Renderer re in ren.renderer.ToList())
    128.                 {
    129.  
    130.                     Transform myParentForSib = re.transform.parent;
    131.  
    132.                     foreach (var chil in myParentForSib.GetComponentsInChildren<Transform>())
    133.                     {
    134.                      
    135.                         if (chil != instance.m_RendererInfo[0].renderer[0].transform)
    136.                         {
    137.  
    138.                             if (chil.gameObject.name.Contains("LOD"))
    139.                             {
    140.  
    141.                                 instance.m_RendererInfo[0].renderer.Add(chil.GetComponent<MeshRenderer>());
    142.  
    143.                             }
    144.  
    145.  
    146.                         }
    147.                     }
    148.  
    149.                 }
    150.  
    151.        
    152.  
    153.  
    154.             }
    155.  
    156.         }
    157.     }
    158.     [MenuItem("Assets/Update Scene with Prefab Lightmaps")]
    159.     static void UpdateLightmaps()
    160.     {
    161.         PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
    162.  
    163.         foreach (var instance in prefabs)
    164.         {
    165.             ApplyLightmaps(instance.m_RendererInfo, instance.m_Lightmaps, instance.m_Lightmaps2);
    166.         }
    167.  
    168.         Debug.Log("Prefab lightmaps updated");
    169.     }
    170.  
    171.     [MenuItem("Assets/Bake Prefab Lightmaps")]
    172.     static void GenerateLightmapInfo()
    173.     {
    174.         Debug.ClearDeveloperConsole();
    175.  
    176.         if (Lightmapping.giWorkflowMode != Lightmapping.GIWorkflowMode.OnDemand)
    177.         {
    178.             Debug.LogError("ExtractLightmapData requires that you have baked you lightmaps and Auto mode is disabled.");
    179.             return;
    180.         }
    181.  
    182.         Lightmapping.Bake();
    183.  
    184.         sceneLightmaps = new List<Texture2D_Remap>();
    185.  
    186.         var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
    187.         var resourcePath = LIGHTMAP_RESOURCE_PATH + scene.name;
    188.         var scenePath = System.IO.Path.GetDirectoryName(scene.path) + "/" + scene.name + "/";
    189.  
    190.         PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
    191.  
    192.         foreach (var instance in prefabs)
    193.         {
    194.             var gameObject = instance.gameObject;
    195.             var rendererInfos = new List<RendererInfo>();
    196.             var lightmaps = new List<Texture2D>();
    197.             var lightmaps2 = new List<Texture2D>();
    198.             GenerateLightmapInfo(scenePath, resourcePath, gameObject, rendererInfos, lightmaps, lightmaps2);
    199.  
    200.             instance.m_RendererInfo = rendererInfos;
    201.             instance.m_Lightmaps = lightmaps.ToArray();
    202.             instance.m_Lightmaps2 = lightmaps2.ToArray();
    203.  
    204.             var targetPrefab = PrefabUtility.GetPrefabParent(gameObject) as GameObject;
    205.             if (targetPrefab != null)
    206.             {
    207.                 //Prefab
    208.                 PrefabUtility.ReplacePrefab(gameObject, targetPrefab);
    209.             }
    210.  
    211.             ApplyLightmaps(instance.m_RendererInfo, instance.m_Lightmaps, instance.m_Lightmaps2);
    212.         }
    213.  
    214.         Debug.Log("Update to prefab lightmaps finished");
    215.     }
    216.  
    217.     static void GenerateLightmapInfo(string scenePath, string resourcePath, GameObject root, List<RendererInfo> rendererInfos, List<Texture2D> lightmaps, List<Texture2D> lightmaps2)
    218.     {
    219.         var renderers = root.GetComponentsInChildren<MeshRenderer>();
    220.         foreach (MeshRenderer renderer in renderers)
    221.         {
    222.             if (renderer.lightmapIndex != -1 && renderer.enabled)
    223.             {
    224.                 RendererInfo info = new RendererInfo();
    225.  
    226.                 info.renderer = new List<Renderer>();
    227.                 info.renderer.Add(renderer);
    228.                 info.lightmapOffsetScale = renderer.lightmapScaleOffset;
    229.  
    230.                 Texture2D lightmap = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapFar;
    231.                 Texture2D lightmap2 = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapNear;
    232.                 int sceneLightmapIndex = AddLightmap(scenePath, resourcePath, renderer.lightmapIndex, lightmap, lightmap2);
    233.  
    234.                 info.lightmapIndex = lightmaps.IndexOf(sceneLightmaps[sceneLightmapIndex].lightmap);
    235.                 if (info.lightmapIndex == -1)
    236.                 {
    237.                     info.lightmapIndex = lightmaps.Count;
    238.                     lightmaps.Add(sceneLightmaps[sceneLightmapIndex].lightmap);
    239.                     lightmaps2.Add(sceneLightmaps[sceneLightmapIndex].lightmap2);
    240.                 }
    241.  
    242.                 rendererInfos.Add(info);
    243.             }
    244.         }
    245.     }
    246.  
    247.     static int AddLightmap(string scenePath, string resourcePath, int originalLightmapIndex, Texture2D lightmap, Texture2D lightmap2)
    248.     {
    249.         int newIndex = -1;
    250.  
    251.         for (int i = 0; i < sceneLightmaps.Count; i++)
    252.         {
    253.             if (sceneLightmaps[i].originalLightmapIndex == originalLightmapIndex)
    254.             {
    255.                 return i;
    256.             }
    257.         }
    258.  
    259.         if (newIndex == -1)
    260.         {
    261.             var lightmap_Remap = new Texture2D_Remap();
    262.             lightmap_Remap.originalLightmapIndex = originalLightmapIndex;
    263.             lightmap_Remap.originalLightmap = lightmap;
    264.  
    265.             var filename = scenePath + "Lightmap-" + originalLightmapIndex;
    266.  
    267.             lightmap_Remap.lightmap = GetLightmapAsset(filename + "_comp_light.exr", resourcePath + "_light", originalLightmapIndex, lightmap);
    268.             if (lightmap2 != null)
    269.             {
    270.                 lightmap_Remap.lightmap2 = GetLightmapAsset(filename + "_comp_dir.exr", resourcePath + "_dir", originalLightmapIndex, lightmap2);
    271.             }
    272.  
    273.             sceneLightmaps.Add(lightmap_Remap);
    274.             newIndex = sceneLightmaps.Count - 1;
    275.         }
    276.  
    277.         return newIndex;
    278.     }
    279.  
    280.     static Texture2D GetLightmapAsset(string filename, string resourcePath, int originalLightmapIndex, Texture2D lightmap)
    281.     {
    282.         AssetDatabase.ImportAsset(filename, ImportAssetOptions.ForceUpdate);
    283.         var importer = AssetImporter.GetAtPath(filename) as TextureImporter;
    284.         importer.isReadable = true;
    285.         AssetDatabase.ImportAsset(filename, ImportAssetOptions.ForceUpdate);
    286.  
    287.         var assetLightmap = AssetDatabase.LoadAssetAtPath<Texture2D>(filename);
    288.  
    289.         var assetPath = resourcePath + "-" + originalLightmapIndex + ".asset";
    290.         var newLightmap = Instantiate<Texture2D>(assetLightmap);
    291.  
    292.         AssetDatabase.CreateAsset(newLightmap, assetPath);
    293.  
    294.         newLightmap = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
    295.  
    296.         importer.isReadable = false;
    297.         AssetDatabase.ImportAsset(filename, ImportAssetOptions.ForceUpdate);
    298.  
    299.         return newLightmap;
    300.     }
    301.  
    302.  
    303.  
    304.  
    305.  
    306.  
    307.     #endif
    308.  
    309. }
    **I have changed array to List

    **EDIT**
    Modified script a little
     
    Last edited: Jan 14, 2016
  9. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    That is useful. I got my desktop working again earlier today. So I plan on adding 90 degree rotation support for directional lights soon.
     
    idurvesh likes this.
  10. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    That would be nice for non desktop users...Do you know how can I reduce size of Lightmap textures generated? I am using EXT 4 format still each lightmap giving around 0.5-1 mb 34 generated textures...That's certainly huge for mobile build...
     
  11. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    Modified code to make it work with Multiple objects with LODs

    To use it make sure your heir achy is something like following

    >Parent (With following script)
    -Child
    - LOD_1
    - LOD_2
    -Another Child
    - LOD_1
    - LOD_2



    Code (CSharp):
    1. #if UNITY_EDITOR
    2. using UnityEditor;
    3. #endif
    4. using UnityEngine;
    5. using System.Collections.Generic;
    6. using System.Linq;
    7.  
    8.  
    9. public class PrefabLightmapData : MonoBehaviour
    10. {
    11.     [System.Serializable]
    12.     struct RendererInfo
    13.     {
    14.         public List <Renderer> renderer;
    15.         public int lightmapIndex;
    16.         public Vector4 lightmapOffsetScale;
    17.     }
    18.  
    19.     [SerializeField]
    20.   List<RendererInfo> m_RendererInfo;
    21.     [SerializeField]
    22.     Texture2D[] m_Lightmaps;
    23.     [SerializeField]
    24.     Texture2D[] m_Lightmaps2;
    25.  
    26.     const string LIGHTMAP_RESOURCE_PATH = "Assets/Resources/Lightmaps/";
    27.  
    28.  
    29.  
    30.     [System.Serializable]
    31.     struct Texture2D_Remap
    32.     {
    33.         public int originalLightmapIndex;
    34.         public Texture2D originalLightmap;
    35.         public Texture2D lightmap;
    36.         public Texture2D lightmap2;
    37.     }
    38.  
    39.     static List<Texture2D_Remap> sceneLightmaps = new List<Texture2D_Remap>();
    40.  
    41.     void Awake()
    42.     {
    43.         ApplyLightmaps(m_RendererInfo, m_Lightmaps, m_Lightmaps2);
    44.     }
    45.  
    46.     static void ApplyLightmaps( List <RendererInfo> rendererInfo, Texture2D[] lightmaps, Texture2D[] lightmaps2)
    47.     {
    48.         bool existsAlready = false;
    49.         int counter = 0;
    50.         int[] lightmapArrayOffsetIndex;
    51.  
    52.         if (rendererInfo == null || rendererInfo.Count == 0)
    53.             return;
    54.  
    55.         var settingslightmaps = LightmapSettings.lightmaps;
    56.         var combinedLightmaps = new List<LightmapData>();
    57.         lightmapArrayOffsetIndex = new int[lightmaps.Length];
    58.  
    59.         for (int i = 0; i < lightmaps.Length; i++)
    60.         {
    61.             existsAlready = false;
    62.             for (int j = 0; j < settingslightmaps.Length; j++)
    63.             {
    64.                 if (lightmaps[i] == settingslightmaps[j].lightmapFar)
    65.                 {
    66.                     lightmapArrayOffsetIndex[i] = j;
    67.                     existsAlready = true;
    68.                 }
    69.             }
    70.  
    71.             if (!existsAlready)
    72.             {
    73.                 lightmapArrayOffsetIndex[i] = counter + settingslightmaps.Length;
    74.                 var newLightmapData = new LightmapData();
    75.                 newLightmapData.lightmapFar = lightmaps[i];
    76.                 newLightmapData.lightmapNear = lightmaps2[i];
    77.                 combinedLightmaps.Add(newLightmapData);
    78.                 ++counter;
    79.             }
    80.         }
    81.  
    82.         var combinedLightmaps2 = new LightmapData[settingslightmaps.Length + counter];
    83.         settingslightmaps.CopyTo(combinedLightmaps2, 0);
    84.  
    85.         if (counter > 0)
    86.         {
    87.             for (int i = 0; i < combinedLightmaps.Count; i++)
    88.             {
    89.                 combinedLightmaps2[i + settingslightmaps.Length] = new LightmapData();
    90.                 combinedLightmaps2[i + settingslightmaps.Length].lightmapFar = combinedLightmaps[i].lightmapFar;
    91.                 combinedLightmaps2[i + settingslightmaps.Length].lightmapNear = combinedLightmaps[i].lightmapNear;
    92.             }
    93.         }
    94.  
    95.         ApplyRendererInfo(rendererInfo, lightmapArrayOffsetIndex);
    96.  
    97.         LightmapSettings.lightmaps = combinedLightmaps2;
    98.     }
    99.  
    100.     static void ApplyRendererInfo(List<RendererInfo> infos, int[] arrayOffsetIndex)
    101.     {
    102.         for (int i = 0; i < infos.Count; i++)
    103.         {
    104.             var info = infos[i];
    105.             foreach (Renderer rer in info.renderer)
    106.             {
    107.                 rer.lightmapIndex = arrayOffsetIndex[info.lightmapIndex];
    108.                 rer.lightmapScaleOffset = info.lightmapOffsetScale;
    109.             }
    110.         }
    111.     }
    112.  
    113. #if UNITY_EDITOR
    114.  
    115.  
    116.  
    117.     [MenuItem("Assets/Assign lightmaps to LOD")]
    118.     static void UseMeBeforeUpdatint()
    119.     {
    120.  
    121.         PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
    122.  
    123.         foreach (var instance in prefabs)
    124.         {
    125.  
    126.             List<RendererInfo> tempListOfRender = instance.m_RendererInfo;
    127.  
    128.             foreach (RendererInfo ren in tempListOfRender) {
    129.  
    130.  
    131.  
    132.                 foreach(Renderer re in ren.renderer.ToList())
    133.                 {
    134.  
    135.                     Transform myParentForSib = re.transform.parent;
    136.  
    137.                     foreach (var chil in myParentForSib.GetComponentsInChildren<Transform>())
    138.                     {
    139.  
    140.                         if (chil != ren.renderer[0].transform)
    141.                         {
    142.  
    143.                             if (chil.gameObject.name.Contains("LOD"))
    144.                             {
    145.  
    146.                                 ren.renderer.Add(chil.GetComponent<MeshRenderer>());
    147.  
    148.                        
    149.                             }
    150.  
    151.  
    152.                         }
    153.                     }
    154.  
    155.                 }
    156.  
    157.        
    158.  
    159.  
    160.             }
    161.  
    162.         }
    163.     }
    164.     [MenuItem("Assets/Update Scene with Prefab Lightmaps")]
    165.     static void UpdateLightmaps()
    166.     {
    167.         PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
    168.  
    169.         foreach (var instance in prefabs)
    170.         {
    171.             ApplyLightmaps(instance.m_RendererInfo, instance.m_Lightmaps, instance.m_Lightmaps2);
    172.         }
    173.  
    174.         Debug.Log("Prefab lightmaps updated");
    175.     }
    176.  
    177.     [MenuItem("Assets/Bake Prefab Lightmaps")]
    178.     static void GenerateLightmapInfo()
    179.     {
    180.         Debug.ClearDeveloperConsole();
    181.  
    182.         if (Lightmapping.giWorkflowMode != Lightmapping.GIWorkflowMode.OnDemand)
    183.         {
    184.             Debug.LogError("ExtractLightmapData requires that you have baked you lightmaps and Auto mode is disabled.");
    185.             return;
    186.         }
    187.  
    188.         Lightmapping.Bake();
    189.  
    190.         sceneLightmaps = new List<Texture2D_Remap>();
    191.  
    192.         var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
    193.         var resourcePath = LIGHTMAP_RESOURCE_PATH + scene.name;
    194.         var scenePath = System.IO.Path.GetDirectoryName(scene.path) + "/" + scene.name + "/";
    195.  
    196.         PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
    197.  
    198.         foreach (var instance in prefabs)
    199.         {
    200.             var gameObject = instance.gameObject;
    201.             var rendererInfos = new List<RendererInfo>();
    202.             var lightmaps = new List<Texture2D>();
    203.             var lightmaps2 = new List<Texture2D>();
    204.             GenerateLightmapInfo(scenePath, resourcePath, gameObject, rendererInfos, lightmaps, lightmaps2);
    205.  
    206.             instance.m_RendererInfo = rendererInfos;
    207.             instance.m_Lightmaps = lightmaps.ToArray();
    208.             instance.m_Lightmaps2 = lightmaps2.ToArray();
    209.  
    210.             var targetPrefab = PrefabUtility.GetPrefabParent(gameObject) as GameObject;
    211.             if (targetPrefab != null)
    212.             {
    213.                 //Prefab
    214.                 PrefabUtility.ReplacePrefab(gameObject, targetPrefab);
    215.             }
    216.  
    217.             ApplyLightmaps(instance.m_RendererInfo, instance.m_Lightmaps, instance.m_Lightmaps2);
    218.         }
    219.  
    220.         Debug.Log("Update to prefab lightmaps finished");
    221.     }
    222.  
    223.     static void GenerateLightmapInfo(string scenePath, string resourcePath, GameObject root, List<RendererInfo> rendererInfos, List<Texture2D> lightmaps, List<Texture2D> lightmaps2)
    224.     {
    225.         var renderers = root.GetComponentsInChildren<MeshRenderer>();
    226.         foreach (MeshRenderer renderer in renderers)
    227.         {
    228.             if (renderer.lightmapIndex != -1 && renderer.enabled)
    229.             {
    230.                 RendererInfo info = new RendererInfo();
    231.  
    232.                 info.renderer = new List<Renderer>();
    233.                 info.renderer.Add(renderer);
    234.                 info.lightmapOffsetScale = renderer.lightmapScaleOffset;
    235.  
    236.                 Texture2D lightmap = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapFar;
    237.                 Texture2D lightmap2 = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapNear;
    238.                 int sceneLightmapIndex = AddLightmap(scenePath, resourcePath, renderer.lightmapIndex, lightmap, lightmap2);
    239.  
    240.                 info.lightmapIndex = lightmaps.IndexOf(sceneLightmaps[sceneLightmapIndex].lightmap);
    241.                 if (info.lightmapIndex == -1)
    242.                 {
    243.                     info.lightmapIndex = lightmaps.Count;
    244.                     lightmaps.Add(sceneLightmaps[sceneLightmapIndex].lightmap);
    245.                     lightmaps2.Add(sceneLightmaps[sceneLightmapIndex].lightmap2);
    246.                 }
    247.  
    248.                 rendererInfos.Add(info);
    249.             }
    250.         }
    251.     }
    252.  
    253.     static int AddLightmap(string scenePath, string resourcePath, int originalLightmapIndex, Texture2D lightmap, Texture2D lightmap2)
    254.     {
    255.         int newIndex = -1;
    256.  
    257.         for (int i = 0; i < sceneLightmaps.Count; i++)
    258.         {
    259.             if (sceneLightmaps[i].originalLightmapIndex == originalLightmapIndex)
    260.             {
    261.                 return i;
    262.             }
    263.         }
    264.  
    265.         if (newIndex == -1)
    266.         {
    267.             var lightmap_Remap = new Texture2D_Remap();
    268.             lightmap_Remap.originalLightmapIndex = originalLightmapIndex;
    269.             lightmap_Remap.originalLightmap = lightmap;
    270.  
    271.             var filename = scenePath + "Lightmap-" + originalLightmapIndex;
    272.  
    273.             lightmap_Remap.lightmap = GetLightmapAsset(filename + "_comp_light.exr", resourcePath + "_light", originalLightmapIndex, lightmap);
    274.             if (lightmap2 != null)
    275.             {
    276.                 lightmap_Remap.lightmap2 = GetLightmapAsset(filename + "_comp_dir.exr", resourcePath + "_dir", originalLightmapIndex, lightmap2);
    277.             }
    278.  
    279.             sceneLightmaps.Add(lightmap_Remap);
    280.             newIndex = sceneLightmaps.Count - 1;
    281.         }
    282.  
    283.         return newIndex;
    284.     }
    285.  
    286.     static Texture2D GetLightmapAsset(string filename, string resourcePath, int originalLightmapIndex, Texture2D lightmap)
    287.     {
    288.         AssetDatabase.ImportAsset(filename, ImportAssetOptions.ForceUpdate);
    289.         var importer = AssetImporter.GetAtPath(filename) as TextureImporter;
    290.         importer.isReadable = true;
    291.         AssetDatabase.ImportAsset(filename, ImportAssetOptions.ForceUpdate);
    292.  
    293.         var assetLightmap = AssetDatabase.LoadAssetAtPath<Texture2D>(filename);
    294.  
    295.         var assetPath = resourcePath + "-" + originalLightmapIndex + ".asset";
    296.         var newLightmap = Instantiate<Texture2D>(assetLightmap);
    297.  
    298.         AssetDatabase.CreateAsset(newLightmap, assetPath);
    299.  
    300.         newLightmap = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
    301.  
    302.         importer.isReadable = false;
    303.         AssetDatabase.ImportAsset(filename, ImportAssetOptions.ForceUpdate);
    304.  
    305.         return newLightmap;
    306.     }
    307.  
    308.    
    309.  
    310.  
    311.  
    312.  
    313.     #endif
    314.  
    315. }
     
  12. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    First, the all the LODs should be able to use the same lightmaps as the original LOD0. This is because they're using the same UV space. This is why I say that the PrefabLightmapData should be copied to all the other LOD levels with the LOD0 lightmap data. Second you can change the "Baked Resolution" under the "Baked GI" section of the lighting to a lower resolution. This will generate smaller lightmaps for the LOD0 level.

    https://onedrive.live.com/redir?resid=724A72EB8C06E730!8157&authkey=!ALhReTt5y2KZmA0&v=3&ithint=photo,png
     
  13. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    Yes,with above script I posted you don't need to place PrefabLightmapData onto all LODs ,you just need let it be as it is and it will add LODs into that "Render" element in script like this http://imgur.com/AKoYmnt .So you don't have to maintain various scripts for LODs ....

    For second ,by reducing baked resolution the quality too decreases that's worrisome my resolution is 2...
     
    Last edited: Jan 15, 2016
  14. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    You can go through all your renders and lower their "Scale in Lightmap" for all the ones that are less important. This will help conserve space on the lightmap for the more important details. In the Lightmaps tab you can select "Object". Then select "Renderers". Pick the object you're currently working on, then Change the "Scale In Lightmap" to something like 0.25. The less space it uses the less likely additional lightmap atlases will be created to make room.
     
    idurvesh likes this.
  15. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    If it's still too large after that, you may have to reduce the variety of prefabs at any particular time by streaming in new ones and destroying old ones (along with removing their associated lightmaps).
     
  16. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    Additionally, if your camera is set to a fix angle like a top down game, then you can use a Matcap shader on some of the objects. This simulates fake lighting that looks decent as long as the camera rotation does not change too much.

    https://www.assetstore.unity3d.com/en/#!/content/8221
     
  17. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    That seems handy tip, will look into it though I think it will not make much difference as we have combined all our environment objects into one mesh and ground into another so in any particular prefab there are only two renderer's one for ground and one for enviornment objects.

    I didn't get this one....Plz elaborate more..

    Seems good but my game is 3D more of like mario kart
     
  18. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    You could try overlapping prefabs more. Basically re-texturing existing prefabs and hide and show parts of the prefab. This way they can use the same lightmaps.
     
    idurvesh likes this.
  19. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    If it's like a kart game, try keeping the view range fairly short, and go to dynamic lighting. This would take significantly less memory, it would just require a bit more graphics processing. But this would not be a bad trade if you keep the geometry fairly simple and the number of light sources low.
     
    idurvesh likes this.
  20. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    Umm that's interesting point ........I will check performance and let you know soon...Thanks :)
     
  21. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    Just tried with realtime and baked, With realtime fps is at 18-20 and with lightmapp its way high with 36FPS....May be thats because my game's view is like first person shooter....

    Anyway I able to reduce generated lightmap memory by first changing its format to ext 4 bit then ran script to create prefab lightmapped in Resources folder. I also set max size to 1024 in script which in total reduce memory by 50%
     
  22. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    aah,I noticed that lightmaps are not getting applied on android build ...On editor its do showing properly lightmapped....
     
  23. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
  24. GTD-Carthage

    GTD-Carthage

    Joined:
    Feb 20, 2014
    Posts:
    1
    Hello all, my team and I are trying to create an Android project something in tandem with an endless runner where tiles are added to the scene as the player passes through them. (It's not an endless runner game, however)

    I am currently experiencing some trouble using the script provided here - it was functioning fine (in-Editor, for most part for now as we haven't rolled a device build of any sort yet) when I imported the script initially.

    Today, I added some new assets (models and textures) into my prefab and now hitting "Bake Prefab Lightmaps" results in...

    IndexOutOfRangeException: Array index is out of range.
    PrefabLightmapData.GenerateLightmapInfo (UnityEngine.GameObject root, System.Collections.Generic.List`1 rendererInfos, System.Collections.Generic.List`1 lightmaps) (at Assets/Scripts/PrefabLightmapData.cs:94)
    PrefabLightmapData.GenerateLightmapInfo () (at Assets/Scripts/PrefabLightmapData.cs:69)

    The PrefabLightmapData I initally added to prefab no longer updates as well, and re-adding the script produces the same result with the error above.

    Is there a mistake I may have done outside the script?
     
  25. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    When an error occurs, all remaining assets are not correctly baked. This would be why the old assets are not updating now. I do not think the script I have matches your. Can you provide the code at line 94?
     
  26. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    You can try this revision

    Code (CSharp):
    1. #if UNITY_EDITOR
    2. using UnityEditor;
    3. #endif
    4. using UnityEngine;
    5. using System.Collections.Generic;
    6. using System.Linq;
    7.  
    8. public class PrefabLightmapData : MonoBehaviour
    9. {
    10.     [System.Serializable]
    11.     struct RendererInfo
    12.     {
    13.         public List<Renderer> renderer;
    14.         public int lightmapIndex;
    15.         public Vector4 lightmapOffsetScale;
    16.     }
    17.  
    18.     [SerializeField]
    19.     List<RendererInfo> m_RendererInfo;
    20.     [SerializeField]
    21.     Texture2D[] m_Lightmaps;
    22.     [SerializeField]
    23.     Texture2D[] m_Lightmaps2;
    24.  
    25.     const string LIGHTMAP_RESOURCE_PATH = "Assets/Resources/Lightmaps/";
    26.  
    27.     [System.Serializable]
    28.     struct Texture2D_Remap
    29.     {
    30.         public int originalLightmapIndex;
    31.         public Texture2D originalLightmap;
    32.         public Texture2D lightmap;
    33.         public Texture2D lightmap2;
    34.     }
    35.  
    36.     static List<Texture2D_Remap> sceneLightmaps = new List<Texture2D_Remap>();
    37.  
    38.     void Awake()
    39.     {
    40.         ApplyLightmaps(m_RendererInfo, m_Lightmaps, m_Lightmaps2);
    41.     }
    42.  
    43.     static void ApplyLightmaps(List<RendererInfo> rendererInfo, Texture2D[] lightmaps, Texture2D[] lightmaps2)
    44.     {
    45.         bool existsAlready = false;
    46.         int counter = 0;
    47.         int[] lightmapArrayOffsetIndex;
    48.  
    49.         if (rendererInfo == null || rendererInfo.Count == 0)
    50.             return;
    51.  
    52.         var settingslightmaps = LightmapSettings.lightmaps;
    53.         var combinedLightmaps = new List<LightmapData>();
    54.         lightmapArrayOffsetIndex = new int[lightmaps.Length];
    55.  
    56.         for (int i = 0; i < lightmaps.Length; i++)
    57.         {
    58.             existsAlready = false;
    59.             for (int j = 0; j < settingslightmaps.Length; j++)
    60.             {
    61.                 if (lightmaps[i] == settingslightmaps[j].lightmapFar)
    62.                 {
    63.                     lightmapArrayOffsetIndex[i] = j;
    64.                     existsAlready = true;
    65.                 }
    66.             }
    67.  
    68.             if (!existsAlready)
    69.             {
    70.                 lightmapArrayOffsetIndex[i] = counter + settingslightmaps.Length;
    71.                 var newLightmapData = new LightmapData();
    72.                 newLightmapData.lightmapFar = lightmaps[i];
    73.                 newLightmapData.lightmapNear = lightmaps2[i];
    74.                 combinedLightmaps.Add(newLightmapData);
    75.                 ++counter;
    76.             }
    77.         }
    78.  
    79.         var combinedLightmaps2 = new LightmapData[settingslightmaps.Length + combinedLightmaps.Count];
    80.         settingslightmaps.CopyTo(combinedLightmaps2, 0);
    81.  
    82.         if (counter > 0)
    83.         {
    84.             for (int i = 0; i < combinedLightmaps.Count; i++)
    85.             {
    86.                 combinedLightmaps2[i + settingslightmaps.Length] = new LightmapData();
    87.                 combinedLightmaps2[i + settingslightmaps.Length].lightmapFar = combinedLightmaps[i].lightmapFar;
    88.                 combinedLightmaps2[i + settingslightmaps.Length].lightmapNear = combinedLightmaps[i].lightmapNear;
    89.             }
    90.         }
    91.  
    92.         ApplyRendererInfo(rendererInfo, lightmapArrayOffsetIndex);
    93.  
    94.         LightmapSettings.lightmaps = combinedLightmaps2;
    95.     }
    96.  
    97.     static void ApplyRendererInfo(List<RendererInfo> infos, int[] arrayOffsetIndex)
    98.     {
    99.         for (int i = 0; i < infos.Count; i++)
    100.         {
    101.             var info = infos[i];
    102.             foreach (Renderer rer in info.renderer)
    103.             {
    104.                 rer.lightmapIndex = arrayOffsetIndex[info.lightmapIndex];
    105.                 rer.lightmapScaleOffset = info.lightmapOffsetScale;
    106.             }
    107.         }
    108.     }
    109.  
    110. #if UNITY_EDITOR
    111.     [MenuItem("Assets/Assign lightmaps to LOD")]
    112.     static void UseMeBeforeUpdatint()
    113.     {
    114.         PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
    115.  
    116.         foreach (var instance in prefabs)
    117.         {
    118.             List<RendererInfo> tempListOfRender = instance.m_RendererInfo;
    119.  
    120.             foreach (RendererInfo ren in tempListOfRender)
    121.             {
    122.                 foreach (Renderer re in ren.renderer.ToList())
    123.                 {
    124.                     Transform myParentForSib = re.transform.parent;
    125.  
    126.                     foreach (var chil in myParentForSib.GetComponentsInChildren<Transform>())
    127.                     {
    128.                         if (chil != ren.renderer[0].transform)
    129.                         {
    130.                             if (chil.gameObject.name.Contains("LOD"))
    131.                             {
    132.                                 ren.renderer.Add(chil.GetComponent<MeshRenderer>());
    133.                             }
    134.                         }
    135.                     }
    136.                 }
    137.             }
    138.         }
    139.     }
    140.  
    141.     [MenuItem("Assets/Update Scene with Prefab Lightmaps")]
    142.     static void UpdateLightmaps()
    143.     {
    144.         PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
    145.  
    146.         foreach (var instance in prefabs)
    147.         {
    148.             ApplyLightmaps(instance.m_RendererInfo, instance.m_Lightmaps, instance.m_Lightmaps2);
    149.         }
    150.  
    151.         Debug.Log("Prefab lightmaps updated");
    152.     }
    153.  
    154.     [MenuItem("Assets/Bake Prefab Lightmaps")]
    155.     static void GenerateLightmapInfo()
    156.     {
    157.         Debug.ClearDeveloperConsole();
    158.  
    159.         if (Lightmapping.giWorkflowMode != Lightmapping.GIWorkflowMode.OnDemand)
    160.         {
    161.             Debug.LogError("ExtractLightmapData requires that you have baked you lightmaps and Auto mode is disabled.");
    162.             return;
    163.         }
    164.  
    165.         Lightmapping.Bake();
    166.  
    167.         sceneLightmaps = new List<Texture2D_Remap>();
    168.  
    169.         var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
    170.         var resourcePath = LIGHTMAP_RESOURCE_PATH + scene.name;
    171.         var scenePath = System.IO.Path.GetDirectoryName(scene.path) + "/" + scene.name + "/";
    172.  
    173.         PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
    174.  
    175.         foreach (var instance in prefabs)
    176.         {
    177.             var gameObject = instance.gameObject;
    178.             var rendererInfos = new List<RendererInfo>();
    179.             var lightmaps = new List<Texture2D>();
    180.             var lightmaps2 = new List<Texture2D>();
    181.             GenerateLightmapInfo(scenePath, resourcePath, gameObject, rendererInfos, lightmaps, lightmaps2);
    182.  
    183.             instance.m_RendererInfo = rendererInfos;
    184.             instance.m_Lightmaps = lightmaps.ToArray();
    185.             instance.m_Lightmaps2 = lightmaps2.ToArray();
    186.  
    187.             var targetPrefab = PrefabUtility.GetPrefabParent(gameObject) as GameObject;
    188.             if (targetPrefab != null)
    189.             {
    190.                 //Prefab
    191.                 PrefabUtility.ReplacePrefab(gameObject, targetPrefab);
    192.             }
    193.  
    194.             ApplyLightmaps(instance.m_RendererInfo, instance.m_Lightmaps, instance.m_Lightmaps2);
    195.         }
    196.  
    197.         Debug.Log("Update to prefab lightmaps finished");
    198.     }
    199.  
    200.     static void GenerateLightmapInfo(string scenePath, string resourcePath, GameObject root, List<RendererInfo> rendererInfos, List<Texture2D> lightmaps, List<Texture2D> lightmaps2)
    201.     {
    202.         var renderers = root.GetComponentsInChildren<MeshRenderer>();
    203.         foreach (MeshRenderer renderer in renderers)
    204.         {
    205.             if (renderer.lightmapIndex != -1 && renderer.enabled)
    206.             {
    207.                 RendererInfo info = new RendererInfo();
    208.  
    209.                 info.renderer = new List<Renderer>();
    210.                 info.renderer.Add(renderer);
    211.                 info.lightmapOffsetScale = renderer.lightmapScaleOffset;
    212.  
    213.                 Texture2D lightmap = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapFar;
    214.                 Texture2D lightmap2 = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapNear;
    215.                 int sceneLightmapIndex = AddLightmap(scenePath, resourcePath, renderer.lightmapIndex, lightmap, lightmap2);
    216.  
    217.                 info.lightmapIndex = lightmaps.IndexOf(sceneLightmaps[sceneLightmapIndex].lightmap);
    218.                 if (info.lightmapIndex == -1)
    219.                 {
    220.                     info.lightmapIndex = lightmaps.Count;
    221.                     lightmaps.Add(sceneLightmaps[sceneLightmapIndex].lightmap);
    222.                     lightmaps2.Add(sceneLightmaps[sceneLightmapIndex].lightmap2);
    223.                 }
    224.  
    225.                 rendererInfos.Add(info);
    226.             }
    227.         }
    228.     }
    229.  
    230.     static int AddLightmap(string scenePath, string resourcePath, int originalLightmapIndex, Texture2D lightmap, Texture2D lightmap2)
    231.     {
    232.         int newIndex = -1;
    233.  
    234.         for (int i = 0; i < sceneLightmaps.Count; i++)
    235.         {
    236.             if (sceneLightmaps[i].originalLightmapIndex == originalLightmapIndex)
    237.             {
    238.                 return i;
    239.             }
    240.         }
    241.  
    242.         if (newIndex == -1)
    243.         {
    244.             var lightmap_Remap = new Texture2D_Remap();
    245.             lightmap_Remap.originalLightmapIndex = originalLightmapIndex;
    246.             lightmap_Remap.originalLightmap = lightmap;
    247.  
    248.             var filename = scenePath + "Lightmap-" + originalLightmapIndex;
    249.  
    250.             lightmap_Remap.lightmap = GetLightmapAsset(filename + "_comp_light.exr", resourcePath + "_light", originalLightmapIndex, lightmap);
    251.             if (lightmap2 != null)
    252.             {
    253.                 lightmap_Remap.lightmap2 = GetLightmapAsset(filename + "_comp_dir.exr", resourcePath + "_dir", originalLightmapIndex, lightmap2);
    254.             }
    255.  
    256.             sceneLightmaps.Add(lightmap_Remap);
    257.             newIndex = sceneLightmaps.Count - 1;
    258.         }
    259.  
    260.         return newIndex;
    261.     }
    262.  
    263.     static Texture2D GetLightmapAsset(string filename, string resourcePath, int originalLightmapIndex, Texture2D lightmap)
    264.     {
    265.         AssetDatabase.ImportAsset(filename, ImportAssetOptions.ForceUpdate);
    266.         var importer = AssetImporter.GetAtPath(filename) as TextureImporter;
    267.         importer.isReadable = true;
    268.         AssetDatabase.ImportAsset(filename, ImportAssetOptions.ForceUpdate);
    269.  
    270.         var assetLightmap = AssetDatabase.LoadAssetAtPath<Texture2D>(filename);
    271.  
    272.         var assetPath = resourcePath + "-" + originalLightmapIndex + ".asset";
    273.         var newLightmap = Instantiate<Texture2D>(assetLightmap);
    274.  
    275.         AssetDatabase.CreateAsset(newLightmap, assetPath);
    276.  
    277.         newLightmap = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
    278.  
    279.         importer.isReadable = false;
    280.         AssetDatabase.ImportAsset(filename, ImportAssetOptions.ForceUpdate);
    281.  
    282.         return newLightmap;
    283.     }
    284. #endif
    285. }
    286.  
     
  27. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    @Centripetal Plz check on your side if script works on android build....Its giving me black line with normal plane and cubes too...works in editor perfectly
     
  28. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    I tried it on my Motorala Druid Turbo on both non-directional and directional lighting modes. It looked fine to me. Have you tried deleting the old lightmapping data before you re-baked your prefabs?
     
  29. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    Also, I've only ever got the stripes when there was a script error message (the script didn't complete due to the error). Do you have any errors in the Console window (Ctrl+Shft+C)?
     
  30. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
  31. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    Yes, I tested it in completely new project by deleting muliple times old lightmaps
    No no error or warning whatsever

    I don't think its gray,
    https://drive.google.com/file/d/0B76Jkcem56IFSzRQb2tkUGZ4Slk/view?usp=sharing

    Here is hows its looking in desktop vs mobile,
    Desktop,
    https://drive.google.com/file/d/0B76Jkcem56IFMEg2TGo3MHVhQjA/view?usp=sharing

    Mobile,
    https://drive.google.com/file/d/0B76Jkcem56IFYTJBZ3d3Mmx6T3M/view?usp=sharing
     
  32. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    You can achieve same result on desktop if you move ApplyLightmaps() from Awake() to Start()....may be there is something with script order execution with some of android devices??
     
  33. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    Start is not called when a prefab is created. Only Awake is.
     
  34. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    Yes ,I am just mentioning that Start behavior is getting replicated into android's awake method....Feeling frustrated now with this bug.....its put our development onto complete halt.....
     
  35. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    Can you provide the exact PrefabLightmapData script you're using?
     
  36. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    Better yet, send me the simple unity project you're using. The one with the cube and plane
     
    idurvesh likes this.
  37. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
  38. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    bretm and idurvesh like this.
  39. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    The problem is with lightmap static batching. You only get this on the device and standalone builds, not in the editor. To fix this, you need to change the prefab to non-static AFTER you bake the lighting. You need the prefab to have lightmap static set when you build the lightmapping data.

    Static Batch checkbox:
    https://drive.google.com/file/d/0B1DjlG6910sTWFFQQWNUMm9KZmc/view?usp=sharing

    Here is a screenshot from my Druid Turbo:
    https://drive.google.com/file/d/0B1DjlG6910sTR2NyemdIdVg0RGs/view?usp=sharing

    Here is the modified project:
    https://drive.google.com/file/d/0B1DjlG6910sTdk1NVDNFVE1CZEk/view?usp=sharing
     
    idurvesh likes this.
  40. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    That worked......Absolute beauty....thank you so much @Centripetal ....
     
  41. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    That's awesome.
     
    idurvesh likes this.
  42. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    Hi,just noticed that we can use Static batching on prefab lightmaps,
    Just add following line in Start(),

    Code (CSharp):
    1.         StaticBatchingUtility.Combine (this.gameObject);
    2.  
    So our script will become,
    Code (CSharp):
    1. #if UNITY_EDITOR
    2. using UnityEditor;
    3. #endif
    4. using UnityEngine;
    5. using System.Collections.Generic;
    6. using System.Linq;
    7. public class PrefabLightmapData : MonoBehaviour
    8. {
    9.     [System.Serializable]
    10.     struct RendererInfo
    11.     {
    12.         public List<Renderer> renderer;
    13.         public int lightmapIndex;
    14.         public Vector4 lightmapOffsetScale;
    15.     }
    16.     [SerializeField]
    17.     List<RendererInfo> m_RendererInfo;
    18.     [SerializeField]
    19.     Texture2D[] m_Lightmaps;
    20.     [SerializeField]
    21.     Texture2D[] m_Lightmaps2;
    22.     const string LIGHTMAP_RESOURCE_PATH = "Assets/Resources/Lightmaps/";
    23.     [System.Serializable]
    24.     struct Texture2D_Remap
    25.     {
    26.         public int originalLightmapIndex;
    27.         public Texture2D originalLightmap;
    28.         public Texture2D lightmap;
    29.         public Texture2D lightmap2;
    30.     }
    31.     static List<Texture2D_Remap> sceneLightmaps = new List<Texture2D_Remap>();
    32.     void Awake()
    33.     {
    34.         ApplyLightmaps(m_RendererInfo, m_Lightmaps, m_Lightmaps2);
    35.     }
    36.      // Use this for initialization
    37.     void Start ()
    38.     {
    39.    
    40.         StaticBatchingUtility.Combine (this.gameObject);
    41.     }
    42.     static void ApplyLightmaps(List<RendererInfo> rendererInfo, Texture2D[] lightmaps, Texture2D[] lightmaps2)
    43.     {
    44.         bool existsAlready = false;
    45.         int counter = 0;
    46.         int[] lightmapArrayOffsetIndex;
    47.         if (rendererInfo == null || rendererInfo.Count == 0)
    48.             return;
    49.         var settingslightmaps = LightmapSettings.lightmaps;
    50.         var combinedLightmaps = new List<LightmapData>();
    51.         lightmapArrayOffsetIndex = new int[lightmaps.Length];
    52.         for (int i = 0; i < lightmaps.Length; i++)
    53.         {
    54.             existsAlready = false;
    55.             for (int j = 0; j < settingslightmaps.Length; j++)
    56.             {
    57.                 if (lightmaps[i] == settingslightmaps[j].lightmapFar)
    58.                 {
    59.                     lightmapArrayOffsetIndex[i] = j;
    60.                     existsAlready = true;
    61.                 }
    62.             }
    63.             if (!existsAlready)
    64.             {
    65.                 lightmapArrayOffsetIndex[i] = counter + settingslightmaps.Length;
    66.                 var newLightmapData = new LightmapData();
    67.                 newLightmapData.lightmapFar = lightmaps[i];
    68.                 newLightmapData.lightmapNear = lightmaps2[i];
    69.                 combinedLightmaps.Add(newLightmapData);
    70.                 ++counter;
    71.             }
    72.         }
    73.         var combinedLightmaps2 = new LightmapData[settingslightmaps.Length + combinedLightmaps.Count];
    74.         settingslightmaps.CopyTo(combinedLightmaps2, 0);
    75.         if (counter > 0)
    76.         {
    77.             for (int i = 0; i < combinedLightmaps.Count; i++)
    78.             {
    79.                 combinedLightmaps2[i + settingslightmaps.Length] = new LightmapData();
    80.                 combinedLightmaps2[i + settingslightmaps.Length].lightmapFar = combinedLightmaps[i].lightmapFar;
    81.                 combinedLightmaps2[i + settingslightmaps.Length].lightmapNear = combinedLightmaps[i].lightmapNear;
    82.             }
    83.         }
    84.         ApplyRendererInfo(rendererInfo, lightmapArrayOffsetIndex);
    85.         LightmapSettings.lightmaps = combinedLightmaps2;
    86.     }
    87.     static void ApplyRendererInfo(List<RendererInfo> infos, int[] arrayOffsetIndex)
    88.     {
    89.         for (int i = 0; i < infos.Count; i++)
    90.         {
    91.             var info = infos[i];
    92.             foreach (Renderer rer in info.renderer)
    93.             {
    94.                 rer.lightmapIndex = arrayOffsetIndex[info.lightmapIndex];
    95.                 rer.lightmapScaleOffset = info.lightmapOffsetScale;
    96.             }
    97.         }
    98.     }
    99. #if UNITY_EDITOR
    100.     [MenuItem("Assets/Assign lightmaps to LOD")]
    101.     static void UseMeBeforeUpdatint()
    102.     {
    103.         PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
    104.         foreach (var instance in prefabs)
    105.         {
    106.             List<RendererInfo> tempListOfRender = instance.m_RendererInfo;
    107.             foreach (RendererInfo ren in tempListOfRender)
    108.             {
    109.                 foreach (Renderer re in ren.renderer.ToList())
    110.                 {
    111.                     Transform myParentForSib = re.transform.parent;
    112.                     foreach (var chil in myParentForSib.GetComponentsInChildren<Transform>())
    113.                     {
    114.                         if (chil != ren.renderer[0].transform)
    115.                         {
    116.                             if (chil.gameObject.name.Contains("LOD"))
    117.                             {
    118.                                 ren.renderer.Add(chil.GetComponent<MeshRenderer>());
    119.                             }
    120.                         }
    121.                     }
    122.                 }
    123.             }
    124.         }
    125.     }
    126.     [MenuItem("Assets/Update Scene with Prefab Lightmaps")]
    127.     static void UpdateLightmaps()
    128.     {
    129.         PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
    130.         foreach (var instance in prefabs)
    131.         {
    132.             ApplyLightmaps(instance.m_RendererInfo, instance.m_Lightmaps, instance.m_Lightmaps2);
    133.         }
    134.         Debug.Log("Prefab lightmaps updated");
    135.     }
    136.     [MenuItem("Assets/Bake Prefab Lightmaps")]
    137.     static void GenerateLightmapInfo()
    138.     {
    139.         Debug.ClearDeveloperConsole();
    140.         if (Lightmapping.giWorkflowMode != Lightmapping.GIWorkflowMode.OnDemand)
    141.         {
    142.             Debug.LogError("ExtractLightmapData requires that you have baked you lightmaps and Auto mode is disabled.");
    143.             return;
    144.         }
    145.         Lightmapping.Bake();
    146.         sceneLightmaps = new List<Texture2D_Remap>();
    147.         var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
    148.         var resourcePath = LIGHTMAP_RESOURCE_PATH + scene.name;
    149.         var scenePath = System.IO.Path.GetDirectoryName(scene.path) + "/" + scene.name + "/";
    150.         PrefabLightmapData[] prefabs = FindObjectsOfType<PrefabLightmapData>();
    151.         foreach (var instance in prefabs)
    152.         {
    153.             var gameObject = instance.gameObject;
    154.             var rendererInfos = new List<RendererInfo>();
    155.             var lightmaps = new List<Texture2D>();
    156.             var lightmaps2 = new List<Texture2D>();
    157.             GenerateLightmapInfo(scenePath, resourcePath, gameObject, rendererInfos, lightmaps, lightmaps2);
    158.             instance.m_RendererInfo = rendererInfos;
    159.             instance.m_Lightmaps = lightmaps.ToArray();
    160.             instance.m_Lightmaps2 = lightmaps2.ToArray();
    161.             var targetPrefab = PrefabUtility.GetPrefabParent(gameObject) as GameObject;
    162.             if (targetPrefab != null)
    163.             {
    164.                 //Prefab
    165.                 PrefabUtility.ReplacePrefab(gameObject, targetPrefab);
    166.             }
    167.             ApplyLightmaps(instance.m_RendererInfo, instance.m_Lightmaps, instance.m_Lightmaps2);
    168.         }
    169.         Debug.Log("Update to prefab lightmaps finished");
    170.     }
    171.     static void GenerateLightmapInfo(string scenePath, string resourcePath, GameObject root, List<RendererInfo> rendererInfos, List<Texture2D> lightmaps, List<Texture2D> lightmaps2)
    172.     {
    173.         var renderers = root.GetComponentsInChildren<MeshRenderer>();
    174.         foreach (MeshRenderer renderer in renderers)
    175.         {
    176.             if (renderer.lightmapIndex != -1 && renderer.enabled)
    177.             {
    178.                 RendererInfo info = new RendererInfo();
    179.                 info.renderer = new List<Renderer>();
    180.                 info.renderer.Add(renderer);
    181.                 info.lightmapOffsetScale = renderer.lightmapScaleOffset;
    182.                 Texture2D lightmap = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapFar;
    183.                 Texture2D lightmap2 = LightmapSettings.lightmaps[renderer.lightmapIndex].lightmapNear;
    184.                 int sceneLightmapIndex = AddLightmap(scenePath, resourcePath, renderer.lightmapIndex, lightmap, lightmap2);
    185.                 info.lightmapIndex = lightmaps.IndexOf(sceneLightmaps[sceneLightmapIndex].lightmap);
    186.                 if (info.lightmapIndex == -1)
    187.                 {
    188.                     info.lightmapIndex = lightmaps.Count;
    189.                     lightmaps.Add(sceneLightmaps[sceneLightmapIndex].lightmap);
    190.                     lightmaps2.Add(sceneLightmaps[sceneLightmapIndex].lightmap2);
    191.                 }
    192.                 rendererInfos.Add(info);
    193.             }
    194.         }
    195.     }
    196.     static int AddLightmap(string scenePath, string resourcePath, int originalLightmapIndex, Texture2D lightmap, Texture2D lightmap2)
    197.     {
    198.         int newIndex = -1;
    199.         for (int i = 0; i < sceneLightmaps.Count; i++)
    200.         {
    201.             if (sceneLightmaps[i].originalLightmapIndex == originalLightmapIndex)
    202.             {
    203.                 return i;
    204.             }
    205.         }
    206.         if (newIndex == -1)
    207.         {
    208.             var lightmap_Remap = new Texture2D_Remap();
    209.             lightmap_Remap.originalLightmapIndex = originalLightmapIndex;
    210.             lightmap_Remap.originalLightmap = lightmap;
    211.             var filename = scenePath + "Lightmap-" + originalLightmapIndex;
    212.             lightmap_Remap.lightmap = GetLightmapAsset(filename + "_comp_light.exr", resourcePath + "_light", originalLightmapIndex, lightmap);
    213.             if (lightmap2 != null)
    214.             {
    215.                 lightmap_Remap.lightmap2 = GetLightmapAsset(filename + "_comp_dir.exr", resourcePath + "_dir", originalLightmapIndex, lightmap2);
    216.             }
    217.             sceneLightmaps.Add(lightmap_Remap);
    218.             newIndex = sceneLightmaps.Count - 1;
    219.         }
    220.         return newIndex;
    221.     }
    222.     static Texture2D GetLightmapAsset(string filename, string resourcePath, int originalLightmapIndex, Texture2D lightmap)
    223.     {
    224.         AssetDatabase.ImportAsset(filename, ImportAssetOptions.ForceUpdate);
    225.         var importer = AssetImporter.GetAtPath(filename) as TextureImporter;
    226.         importer.isReadable = true;
    227.         AssetDatabase.ImportAsset(filename, ImportAssetOptions.ForceUpdate);
    228.         var assetLightmap = AssetDatabase.LoadAssetAtPath<Texture2D>(filename);
    229.         var assetPath = resourcePath + "-" + originalLightmapIndex + ".asset";
    230.         var newLightmap = Instantiate<Texture2D>(assetLightmap);
    231.         AssetDatabase.CreateAsset(newLightmap, assetPath);
    232.         newLightmap = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath);
    233.         importer.isReadable = false;
    234.         AssetDatabase.ImportAsset(filename, ImportAssetOptions.ForceUpdate);
    235.         return newLightmap;
    236.     }
    237. #endif
    238. }
     
  43. Centripetal

    Centripetal

    Joined:
    May 31, 2013
    Posts:
    90
    That's good to know. Thanks for sharing
     
    idurvesh likes this.
  44. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    Always welcome :)
     
  45. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    473
    Hi,Unity guys have replied to my bug report about "Texture2D" not been saved from LightMapAsset....They replied me that they have been able to reproduce the bug and sent to developers.

    So hopefully from next update we do not have to worry about managing and creating lightmaps two times for single scene.
     
  46. dangermousenz

    dangermousenz

    Joined:
    Feb 9, 2013
    Posts:
    1
    Hi everyone, I have to say, the work and collaboration in this thread is very impressive. Long story short, I recently upgraded from Unity4 to 5, and am having this exact issue.

    However, I have a problem. I would consider myself intermediate at best when it comes to this stuff. I can set up my lights, I am (was) able to bake my lightmaps, and I've got all sorts of working code, although virtually no editor code, that runs quite well. But a lot of what's going on in that script up above, is just a wee bit over my head.

    At the end of the day, all I would want is my prefabs (each one is quite large, they're low detail city blocks), with their own lightmaps (I wouldn't necessarily want one single massive set of lightmaps), and be able to instantiate them at runtime. That doesn't seem like it should be that hard :(

    Would any of you be kind enough to maybe make a version of that script that is bare-bones enough for me to use? Or, in a perfect world, do a tutorial style write up of it that I could follow along with, and be able to modify as I see fit, taking and leaving the bits I need? I realise that I'm asking a LOT, and definitely have no expectations of anyone.

    If it comes to this weekend and no one has been able to, I'll pick that script apart myself, and learn some more about writing editor scripts and directives, and what's actually happening with the lightmaps behind the scenes, and see what I can come up with. And if/when I fail at that, I may resort to making my lightmaps manually in maya and setting it all up in custom shaders, which is more my area of expertise.

    As a side note, and this is NOT a criticism, I really feel like this workflow is something that should be addressed by Unity. I kind of understand why they've made the change, and why they won't change it back. But what I don't understand is why they can't provide an alternative, or at least the tools and components required to assemble them yourself.

    Thanks guys
     
  47. igor-pchelko-nov

    igor-pchelko-nov

    Joined:
    Oct 19, 2015
    Posts:
    2
    Hi everyone, thank you all for to approach that allows to use lightmapped prefabs.

    I've adopted it to use it in assetBundles, however, in this case, one part is missed - Reflection Probes.
    I've adopted it to use it in assetBundles, however, in this case, one part is missed - Reflection Probes.
    Does someone tried to save/load reflection probes for similar cases?

    Thank you in advance.
     
    Last edited: Feb 4, 2016
  48. pahe

    pahe

    Joined:
    May 10, 2011
    Posts:
    420
    Hi guys. First of all thanks for the efforts you put into this.

    With the help of your scripts I was able to fix our lightmap baking system again. But I wonder how you solved the problem of not being able to change the texture compression of the cloned lightmap textures. Did you write a custom assetimporter for that? The baked lightmap textures are about 1.7 mb while the assets created via AssetDatabase.CreateAsset are 11 mb, which is a real problem.

    Update: Ok, nevermind guys. Though one moment about it and found the solution ^^ Instead of creating a new asset, I copied the lightmap texture and stored it as ".png" file.
     
  49. Culzean

    Culzean

    Joined:
    Jan 25, 2014
    Posts:
    47
    Hello,
    Can first say that when this is working it's looks amazing is works well. However I am finding this a bit temperamental to get good results. Can I check, does this work across multiple materials and textures?
     
  50. Culzean

    Culzean

    Joined:
    Jan 25, 2014
    Posts:
    47
    I have found where my issue is. Perhaps someone can suggest a solution.
    I wish to manually edit the uvs so that a single texture is fitted to a number of hexes. Where the hex is a single prefab.
    This worked well enough by editing the maintextureoffset. But editing this property makes any static batching invalid! so I moved the edit to the mesh UVs, this mesh is only used with this texture. This side stepped the issue of editing the material however this edit appears to conflict with the prefab lightmap workings. I shall look into where the collision is taking place.

    I wish to get light mapping, static batching and dynamic texturing to work harmoniously at once. Any thoughts in how to achieve this?

    Many thanks.
     
Thread Status:
Not open for further replies.