Search Unity

Disable baked lightmaps at runtime on mobiles

Discussion in 'Scripting' started by Durins-Bane, Jun 30, 2016.

  1. Durins-Bane

    Durins-Bane

    Joined:
    Sep 21, 2012
    Posts:
    175
    Is it possible to turn off baked light maps for a scene while its being played?

    I want my game to be able to run on pretty much any device and up to now its working pretty well :D

    The phone I use for testing is right on the bottom end of the scale and without any light maps/realtime lighting it just about runs 25fps+ and is playable (most of the time depending on how many mobs are spawned)

    For people with better phones though that run my game easily with high fps I want to make it look a little bit nicer and more pleasing for them rather than unrealistic lighting and no shadows.
    I have settings so that they can change the quality in game which works perfectly.

    Is it possible to load my game and then enable/disable the light maps of a scene on mobile and have it affect performance depending on which quality setting are selected?

    I found this post from 2011/13
    http://forum.unity3d.com/threads/turn-use-lightmaps-off-via-script.75794/#post-485421

    Will this work with Unity5? Has anyone done this recently?
    Does this effect performance on mobiles rather than just hiding them?

    Im going to test it out tomorrow when I have time just wondering if anyone has tried it before on mobiles.
     
  2. Durins-Bane

    Durins-Bane

    Joined:
    Sep 21, 2012
    Posts:
    175
    If anyone is interested in trying to do this here is some code I found that works pretty well


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class lightmapData : MonoBehaviour {
    5.    
    6.     //reference to existing scene lightmap data.
    7.     LightmapData[] lightmap_data;
    8.  
    9.     // Use this for initialization
    10.     void Start () {
    11.         // Save reference to existing scene lightmap data.
    12.         lightmap_data = LightmapSettings.lightmaps;}
    13.  
    14.     public void disableLightmaps(){
    15.         // Disable lightmaps in scene by removing the lightmap data references
    16.         LightmapSettings.lightmaps = new LightmapData[]{};}
    17.    
    18.     public void enableLightmaps(){
    19.         // Reenable lightmap data in scene.
    20.         LightmapSettings.lightmaps = lightmap_data;}}
    21.  
     
  3. torreb1990

    torreb1990

    Joined:
    Apr 5, 2018
    Posts:
    2
    Thank you show much. I lost a lot of time looking for a solution and this one work perfectly :D
     
    Lisk likes this.
  4. secondimpactgames

    secondimpactgames

    Joined:
    Feb 24, 2014
    Posts:
    1
    This thread comes up top when googling to disable lightmaps in code - for anyone arriving here from a search like I did: the above approach no longer works. If you replace the lightmaps with an empty array Unity will pass a default (grey) texture to materials instead. This means that instead of turning off the baked lighting, you're swapping it for a uniformly lit version.

    I got around this by building a copy of the original lightmap data array, and replacing the lightmapColor texture on each LightmapData object with a black texture. As follows:

    Code (CSharp):
    1. LightmapData[] turnedOffLightmaps = new LightmapData[originalLightmaps.Length];
    2.  
    3. for(int i = 0; i < turnedOffLightmaps.Length; i++)
    4. {
    5.     var thisOriginalLightmap = originalLightmaps[i];
    6.     var thisTurnedOffLightmap = new LightmapData();
    7.  
    8.      thisTurnedOffLightmap.lightmapDir = thisOriginalLightmap.lightmapDir;
    9.     thisTurnedOffLightmap.shadowMask = thisOriginalLightmap.shadowMask;
    10.     thisTurnedOffLightmap.lightmapColor = blackTexture;
    11.  
    12.     turnedOffLightmaps[i] = thisTurnedOffLightmap;
    13. }
    14.  
    15. LightmapSettings.lightmaps = turnedOffLightmaps;
     
    MagiJedi and th3z0d1ac like this.
  5. th3z0d1ac

    th3z0d1ac

    Joined:
    May 14, 2014
    Posts:
    15
    Thanks for the suggestion/solution, really appreciate it!
     
  6. alexlopnog

    alexlopnog

    Joined:
    Nov 25, 2019
    Posts:
    1
    hello! sorry i'm quite new to coding, when i try to use this script, the compiler says that the name originalLightmaps doesn't exist in the current context. please, could you provide a detailed explanation as how to use your script? thanks a lot!
     
  7. Pandazole

    Pandazole

    Joined:
    Sep 23, 2019
    Posts:
    28
    "doesn't exist in the current context" means the variable, which is "originalLightmaps" in this case is not declared yet. So basically you need to declare (write) this variable before, in other words, write ( LightmapData[] originalLightmaps; ) inside your class. Note also the "blackTexture" is not declared too, do the same for it. Final code should be like:


    Code (CSharp):
    1.     LightmapData[] originalLightmaps;
    2.     Texture2D blackTexture;
    3.     private void Start()
    4.     {
    5.         LightmapData[] turnedOffLightmaps = new LightmapData[originalLightmaps.Length];
    6.         for (int i = 0; i < turnedOffLightmaps.Length; i++)
    7.         {
    8.             var thisOriginalLightmap = originalLightmaps[i];
    9.             var thisTurnedOffLightmap = new LightmapData();
    10.  
    11.             thisTurnedOffLightmap.lightmapDir = thisOriginalLightmap.lightmapDir;
    12.             thisTurnedOffLightmap.shadowMask = thisOriginalLightmap.shadowMask;
    13.             thisTurnedOffLightmap.lightmapColor = blackTexture;
    14.  
    15.             turnedOffLightmaps[i] = thisTurnedOffLightmap;
    16.         }
    17.  
    18.     }
     
  8. sarahnorthway

    sarahnorthway

    Joined:
    Jul 16, 2015
    Posts:
    78
    For my project I wanted to disable the lightmaps on GI-static objects, and have them go back to being affected by (dynamic) fog and environment ambient color, as if I had completely disabled baked lighting. The above code doesn't support fog or ambient light because it was baked into the (now black) lightmaps.

    My solution was to set Renderer.lightmapIndex to -1 on every GI-static object. I packaged it as a component beside every Renderer (also Terrain). Feels hacky? But I don't have many baked objects.

    Code (CSharp):
    1. public class LightmapSwitcher : MonoBehaviour {
    2.    
    3.     private static List<LightmapSwitcher> switchers = new List<LightmapSwitcher>();
    4.     private int originalIndex = -1;
    5.    
    6.     private void Awake() {
    7.         switchers.Add(this);
    8.         Renderer ren = GetComponent<Renderer>();
    9.         if (ren != null) {
    10.             originalIndex = ren.lightmapIndex;
    11.         } else {
    12.             originalIndex = GetComponent<Terrain>()?.lightmapIndex ?? -1;
    13.         }
    14.     }
    15.  
    16.     public void ToggleLights(bool value) {
    17.         if (this == null) return;
    18.         Renderer ren = GetComponent<Renderer>();
    19.         if (ren != null) {
    20.             if (value) {
    21.                 ren.lightmapIndex = originalIndex;
    22.             } else {
    23.                 ren.lightmapIndex = -1;
    24.             }
    25.         } else {
    26.             Terrain terrain = GetComponent<Terrain>();
    27.             if (terrain != null) {
    28.                 if (value) {
    29.                     terrain.lightmapIndex = originalIndex;
    30.                 } else {
    31.                     terrain.lightmapIndex = -1;
    32.                 }
    33.             }
    34.         }
    35.     }
    36.  
    37.     public static void Night() {
    38.         foreach (LightmapSwitcher switcher in switchers) switcher.ToggleLights(true);
    39.     }
    40.  
    41.     public static void Day() {
    42.         foreach (LightmapSwitcher switcher in switchers) switcher.ToggleLights(false);
    43.     }
    44. }
     
    JonPQ likes this.