Introduction
Accompanying GitHub Project File: https://github.com/theunitygamedev/Unity2020LightingTutorial
Have you ever seen that annoying little Global Illumination (GI) bar at the bottom right of your Unity Editor screen that keeps getting updated when you move certain objects in your scene and wonder: “What the heck is Global Illumination”?
What does it mean when your lighting gets “baked” into a lightmap? How does direct light differ from indirect lighting? Why is your moving object’s shadow not being casted by your baked area light? In this blog I will go over the basics of lighting in Unity 2020 to give you a head start into the wonderful world of lighting so you can build prettier (or uglier if that’s what you are going for) games.
Direct VS Indirect Lighting
To understand concepts like Baked and Realtime Lighting we first need to grasp the workings of direct and indirect lighting.
Direct Lighting
Direct lighting in Unity includes light with one or zero bounces. In real life this includes a light photon that directly hits your eye from a light source or a light photon that hits an object once, gets reflected and hits your eye. In the image above you can see the direct light photon from the sun directly hitting the lizard’s eye and another direct light ray bouncing off the grey area of the wing and hitting the lizard’s eye. Note that when the white light hits the grey wing area, it picks up some information from the surface and carries that to the eye. In this case the white light morphs to the color grey.
Indirect Light
Indirect light in Unity accounts for light that bounces more than once prior to hitting your eye. Looking at the image above, you can see the white light hitting the red tail of the airplane (changes to red) then hitting the grey are of the wing (mixes the grey and red) and finally landing on the lizard’s eye. In Unity 2020 you can have up to four bounces of indirect light in a scene. This is known as Global Illumination or how the light of one surface affects another surface. You can set the number of surface reflection bounces for indirect lighting by going to Window->Rendering->Lighting->Scene and adjusting number in the “Bounces” drop down:
The higher the number, the more realistic the lighting in your scene will look but the “baking” (more on this further below) of the lightmap will take longer. Strangely, you could set the Bounces value to “None” but still see light bouncing off a surface:
The reason for this: All lights produce at least direct lighting. In the scene above you are now seeing the direct light rays from the baked area light hitting the wall and then the camera / player. There are currently no Global Illumination calculations to be made. Once you set the Bounces for indirect light to 1, you can see the light from the wall on the left bounce one time on surrounding surfaces and back to the camera / player as seen below:
Baked Lightmaps
Trying to simulate realistic lighting in a game can very CPU (Central Processing Unit) or GPU (Graphics Processing Unit) intensive. Programmers are always trying to come up with tricks to reduce the CPU overhead of graphics at runtime. This can be via algorithm optimizations, using sampling points like Light Probes (for another blog) using the GPU instead of CPU or in the case of Unity’s Baked Global Illumination (GI) system, baked lightmaps are used. GI comprises both direct and indirect lighting to produce simple to complex high-fidelity renderings of a lighted environment. Instead of computing the light calculations as the game is running on a device like a Nintendo Switch or in the Unity Player at runtime (when you click play in Unity), the calculations are made while you are working in your scene automatically or manually based on your lightmapping settings. The light calculations are “baked” into the scene when the lightmaps are generated. The downside of the baked lightmaps is they do not change at runtime. If for instance your game character shoots and destroys an object representing a baked light in a game, the shadows and halo that the light generated will remain on surrounding surfaces and make the scene look unrealistic. For this reason, objects need to be marked as “static” to be included in Unity’s Baked GI system. Unity needs to make sure the objects affected by baked lighting will not move during the game. This can be done by opening the inspector window for an object in the Hierarchy and check-marking the static box:
If you were to place a script on a soccer ball marked “static” to move the transform of that ball, you will see the wireframe of the ball moving in the scene view but the ball rendering will remain motionless:
So on an Xbox or in the Unity player window you won’t see that soccer ball moving in the game. Lights can be set to either Baked, Realtime or Mixed modes. To set a light’s mode to Baked, click on the light in the scene and view the “Mode” in the associated inspector panel:
Realtime Lighting
Unity does not pre-compute any lighting information for lights marked as Realtime lights in the “Mode” section in the light’s inspection panel:
All computations will be done at run-time (higher in-gameplay CPU or GPU overhead than Baked lighting) like when your game is running on a PlayStation or in the Player window in Unity. Unity is retiring its Enlighten Realtime system (deprecated in Unity 2020) since the developer, Geomerics is shutting down the project. Enlighten is/was could be used for rendering real-time Global Illuminated (more than 1 bounces of light) scenes. You now must rely on placing light probes (for another tutorial) to sample the light in the surrounding environment for real-time GI lighting while waiting for Unity to finish the replacement system for Enlighten. You can read more about that on this blog: https://forum.unity.com/threads/enlighten-deprecation-and-replacement-solution.697778/?_ga=2.134808243.394525261.1598924181-1083081855.1597975993
A scene using Unity’s deprecated Enlighten system:
You can watch the full video here: https://www.youtube.com/watch?v=3WvzA1yOYEs
Remember, Enlighten was used to produce realtime GI for indirect light to make a scene look more realistic and connected. It bridged the gap for GI moving objects like a tree swaying in the wind and the green of leaves reflecting its colors against a white wall our overhead moving cloud shadows affecting an environment. You can still use baked GI for static objects but there is currently no plug and play solution for realtime indirect light GI.
Back to how moving objects are affected to baked vs realtime light…Here you can see the effects of unchecking the “static” box of the soccer ball when there is only one baked area light that could affect it:
As you can see the soccer ball is unaffected by the baked area light coming from the tv since the soccer ball is NOT marked “static”.
Now I’ve added a blue spotlight configured to a mode of “Realtime” to the scene and turned on a script to make non-static soccer ball move up and down:
As the ball moves into the rays of the spotlight, it becomes illuminated and casts a shadow. In the scene above there are two lights, the baked TV’s area light and the realtime spotlight placed near the camera and directed to the soccer ball. The baked area light coming from the TV does not affect the soccer ball as can be seen below when the soccer ball moves out of the spotlight’s rays back into the TV’s area light’s rays:
Mixed Lighting
Lights configured for the Mixed Lighting mode combine elements of both realtime and baked lighting.
This is useful for instance when you want to have realtime shadows of a moving object affected by the light combined with the static GI baked lighting (more than 1 surface bounces) that the light produces. In the case of a dynamic object like a soccer ball passing in front of the light, the shadow of that ball will be casted on objects that are configured to receive shadows and the light bouncing off objects marked static will contribute to the GI to make the scene look more realistic.
I personally recommend turning off Realtime Global Illumination in your scenes until Unity releases a replacement for Enlighten. If you spend a lot of time on your game getting things just right and attach that to certain rendering pipelines, you could have serious problems down the road with upgrades to your game when updating Unity. You can turn of Realtime GI by going to Window->Rendering->Lighting->Scene->Realtime Lighting and unchecking the “Realtime Global Illumination (Deprecated)” box:
Lightmaps
The process of pre-calculating the brightness of surfaces and then storing the result of those calculations in a lightmap Texture is called lightmapping. Both direct and indirect light can be included. The lightmap information cannot change at runtime but realtime lights can be additively overlaid on top of a lightmapped scene.
Unity 2020 offers the Progressive and the Enlighten (deprecated) lightmappers.
The Progressive Lightmapper
One of the main advantages of using the progressive lightmapper is that you get relatively fast, iterative updates to the scene view while you are working on modifying objects or settings that could trigger a change to the underlying lightmaps. An estimated time is given while the scene is baked that helps developers work more efficiently.
You can choose to have the ligthmaps automatically update (bake) or you can manually bake them. You will know that it is set to automatically update when you move an object that affects the lightmap and you see the Global Illumination bar at the bottom right-hand screen show up:
To change from automatic to manual lightmapping, go to Window->Rendering->Lighting->Scene and uncheck the “Auto Generate” box:
If you don’t want to be bothered with the baking while you are moving around objects in the scene, just switch to manual so there will be less overload in the editor. Once you want to start working on the lighting you can switch back to “Auto Generate”.
The Progressive Lightmapper comes in two flavors, Progressive CPU and Progressive GPU (Preview). I am excited about the Progressive GPU since it can greatly speed up the lightmapping process, depending on your GPU. Instead of running the ligthmapper through your 2-8 CPU cores (2 – 8 different threads doing calculations at the same time), the Unity editor can tap into the hundred to thousands of GPU cores to speed up the renderings. I’ve played with it myself and have seen an improvement in speed with similar quality. To switch between the two lightmappers, go to Window->Rendering->Lighting->Scene->Lightmapping Settings and alter the Lightmapper dropdown:
To view the lightmaps that the lightmapper produces, go to Window->Rendering->Lighting->Baked Lightmaps. If you double click on the thumbnail image, a preview image will open:
Environment Lighting
Have you ever opened a scene in Unity without any lights but could still see objects in the scene? If there are no lights in the Hierarchy then probably there Environment Ambient Lighting is probably turned on. You can check this by going to Window->Rendering->Lighting->Environment Lighting. You can set the source to Skybox, Gradient or Color:
With Ambient Color you can get some cool effects:
If you don’t want any Ambient Color contributing to the scene, set the color to black:
In the scene above, only the baked area light in the TV is contributing to the scene’s lighting.
Types of Lights
There are four types of lights namely Point, Spot, Directional and Area.
Point lights are good for lighting up a specific circular area in your scene like what a desk lamp would do.
Spot lights are similar to point lights but are constrained to an angle resulting in a cone shaped area of illumination.
Directional lights are used primarily to simulate a light source far away like the sun. Moving a directional light up or down or left or right won’t make any noticeable differences in your scene. When you change the direction or angle, you will notice the shade of objects alter.
Area lights are defined by a rectangle space and shine from only one area of the rectangle. These are good for simulating something like a TV screen like I used in this project.
You can read more about lights in Unity here: https://docs.unity3d.com/Manual/class-Light.html
Wrap it Up
As mentioned in the title of this tutorial, it is meant for beginners. I wanted to go over the main concepts to give you a jump start in the amazing world of Unity lighting. I myself will continue to learn more in-depth concept and make deeper dive tutorials in the future. Please remember to favorite theunitygamedev.com and subscribe to my youtube channel, theunitygamedev at https://www.youtube.com/channel/UCrK5M0Ug-aCsAIADL_Q25bA/
I wish you good tidings with your game development. Keep moving forward. Keep building. -TheUnityGameDev
Last modified: September 13, 2020