Lighting and Rendering
Lighting and Rendering
Lighting and Rendering
COVID-19 Support:
We’re providing all users three months of complimentary access to Unity Learn Premium, from
March 19 to June 20, 2020.
Projects
Courses
Tutorials
Learn Live
Topics
Premium
Figure 01: The same scene: With no lighting (Left), with ‘direct light’ only (Center) & with indirect
'global illumination' (Right). Note how colors are transferred as light ‘bounces’ between surfaces,
giving a much more realistic result.
In this tutorial, we will give you an overview of how GI works in Unity. We will walk you through
the different lighting techniques available, explain how to set up your project for lighting and then
explore the various tools at your disposal when considering how to light a scene.
Realtime Lighting
By default, lights in Unity - directional, spot and point, are realtime. This means that they contribute
direct light to the scene and update every frame. As lights and GameObjects are moved within the
scene, lighting will be updated immediately. This can be observed in both the scene and game views
(Figure 02).
Figure 02: The effect of realtime light alone. Note that shadows are completely black as there is no
bounced light. Only surfaces falling within the cone of the Spotlight are affected.
Realtime lighting is the most basic way of lighting objects within the scene and is useful for
illuminating characters or other movable geometry.
Unfortunately, the light rays from Unity’s realtime lights do not bounce when they are used by
themselves. In order to create more realistic scenes using techniques such as global illumination, we
need to enable Unity’s precomputed lighting solutions.
Baked GI Lighting
When 'baking’ a ‘lightmap', the effects of light on static objects in the scene are calculated and the
results are written to textures that are overlaid on top of scene geometry to create the effect of
lighting (Figure 03).
Figure 03: Left: A simple lightmapped scene. Right: The lightmap texture generated by Unity. Note
how both shadow and light information is captured.
These ‘lightmaps’ can include both the direct light which strikes a surface and also the ‘indirect’
light that bounces from other objects or surfaces within the scene. This lighting texture can be used
together with surface information like the color (albedo) and relief (normals) by the ‘Shader’
associated with an object’s material.
With baked lighting, these light textures (lightmaps) cannot change during gameplay and so are
referred to as ‘static’. Realtime lights can be overlaid and used additively on top of a lightmapped
scene but cannot interactively change the lightmaps themselves.
With this approach, we trade the ability to move our lights at gameplay for a potential increase in
performance, suiting less powerful hardware such as mobile platforms.
Figure 05: Left: With scene view set to ‘Albedo’ the texels generated by Unity’s Precomputed
Realtime GI can clearly be seen. By default, a texel in this view is roughly the size of a cluster.
Right: The scene as it appears in-game once the lighting has been calculated and the results
converted to lightmap textures and applied.
Traditionally when calculating global illumination, we would ‘ray trace’ light rays as they bounce
around the static scene. This is very processing intensive and therefore too demanding to be updated
in realtime. Instead, Unity uses ray tracing to calculate the relationships between these surface
clusters beforehand - during the 'Light Transport' stage of the precompute.
By simplifying the world into a network of relationships, we remove the need for expensive ray
tracing during the performance-critical gameplay processes.
We have effectively created a simplified mathematical model of the world which can be fed
different input during gameplay. This means we can make modifications to lights, or surface colors
within the scene and quickly see the effects of GI in scene lighting update at interactive frame rates.
The resulting output from our lighting model can then be turned into lightmap textures for rendering
on the GPU, blended with other lighting and surface maps, processed for effects and finally output
to the screen.
Benefits and Costs
Although it is possible to simultaneously use Baked GI lighting and Precomputed Realtime GI, be
wary that the performance cost of rendering both systems simultaneously is exactly the sum of them
both. Not only do we have to store both sets of lightmaps in video memory, but we also pay the
processing cost of decoding both in shaders.
The cases in which you may wish to choose one lighting method over another depend on the nature
of your project and the performance capabilities of your intended hardware. For example, on mobile
where video memory and processing power are more limited, it is likely that a Baked GI lighting
approach would be more performant. On ‘standalone computers’ with dedicated graphics hardware
or recent games consoles, it is quite possible to use Precomputed Realtime GI or even to use both
systems simultaneously.
The decision on which approach to take will have to be evaluated based on the nature of your
particular project and desired target platform. Remember that when targeting a range of different
hardware, that often it is the least performant which will determine which approach is needed.
Per-Light Settings
The default baking mode for each light is Realtime. This means that the selected light(s) will still
contribute direct light to your scene, with indirect light handled by Unity’s Precomputed Realtime
GI system.
However, if the baking mode is set to Baked then that light will contribute lighting solely to Unity’s
Baked GI system. Both direct and indirect light from those lights selected will be baked into
lightmaps and cannot be changed during gameplay.
Figure 06: Point light with the per-light Baking mode set to ‘Realtime’.
Selecting the Mixed baking mode, GameObjects marked as static will still include this light in their
Baked GI lightmaps. However, unlike lights marked as ‘Baked’, Mixed lights will still contribute
realtime, direct light to non-static GameObjects within your scene. This can be useful in cases
where you are using lightmaps in your static environment, but you still want a character to use these
same lights to cast realtime shadows on lightmapped geometry.
Figure 07: Progress bar showing the current state of Unity’s precompute.
In the example above, we can see that auto generate lighting is on and that it is preparing to bake.
The various stages of the baking are listed below:
Precomputed Realtime GI:
1. Create Geometry
2. Layout Systems
3. Create Systems
4. Create Atlas
5. Clustering
6. Visibility
7. Light Transport
8. Tetrahedralize Probes
9. Create ProbeSet
Probes
1. Ambient Probes
2. Baked/Realtime Ref. Probes
Baked GI
1. Create Geometry
2. Atlassing
3. Create Baked Systems
4. Baked Resources
5. Baked AO
6. Export Baked Texture
7. Bake Visibility
8. Bake Direct
9. Ambient and Emissive
10.Create Bake Systems
11.Bake Runtime
12.Upsampling Visibility
13.Bake Indirect
14.Final Gather
15.Bake ProbesSet
16.Compositing
Starting a Precompute
Only static geometry is considered by Unity’s precomputed lighting solutions. To begin the lighting
precompute process we need at least one GameObject marked as ‘static’ in our scene. This can
either be done individually or by shift-selecting multiple GameObjects from the hierarchy panel.
From the Inspector panel, the Static checkbox can be selected Inspector > Static. This will set all
of the GameObject’s ‘static options’, or ‘flags’, including navigation and batching, to be static,
which may not be desirable. For Precomputed Realtime GI, only 'Lightmap Static' needs to be
checked.
For more fine-grained control, individual static options can be set from the drop-down list
accessible to the right of the Static checkbox in the Inspector panel. Additionally, objects can also
be set to Static in the Object area of the lighting window.
If your scene is set to Auto Lighting > Scene > Auto, Unity’s lighting precomputes will now begin
automatically. Otherwise, it will need to be started manually as described below.
Auto/Manual Precompute
If ‘Auto’ is checked from the bottom of Unity’s Lighting panel Window > Rendering > Lighting
Settings > Auto Generate, then this precompute will begin automatically as a background process
whenever changes are made to static geometry within your scene.
However, if Auto is not selected, you will need to manually start a precompute by clicking the
Generate Lighting button next to it. This will begin the precompute in much the same way while
giving you control over when this process starts.
Manually initiating a precompute will cause all aspects of your scene lighting to be evaluated and
(re)computed. If you wish to selectively recalculate Reflection probes by themselves, this can be
done by clicking the arrow on the Generate Lighting button to display a dropdown Window >
Rendering > Lighting Settings > Generate Lighting.
GI Cache
In either Baked GI or Precomputed Realtime GI, Unity ‘caches’ (stores) data about your scene
lighting in the ‘GI Cache’, and will try to reuse this data whenever possible to save time during
precomputing. The number and nature of the changes you have made to your scene will determine
how much of this data can be reused, if at all.
This cache is stored outside of your Unity project and can be cleared using Preference > GI Cache
> Clear Cache. Clearing this means that all stages of the precompute will need to be recalculated
from the beginning and this can, therefore, be time-consuming. However, in some cases, where
perhaps you need to reduce disk usage, this may be helpful.
Forward Rendering
In Forward Rendering, each object is rendered in a ‘pass’ for each light that affects it. Therefore
each object might be rendered multiple times depending upon how many lights are within range.
The advantage of this approach is that it can be very fast - meaning hardware requirements are
lower than alternatives. Additionally, Forward Rendering offers us a wide range of custom ‘shading
models’ and can handle transparency quickly. It also allows for the use of hardware techniques like
‘multi-sample anti-aliasing’ (MSAA) which are not available in other alternatives, such as Deferred
Rendering which can have a great impact on image quality.
However, a significant disadvantage of the forward path is that we have to pay a render cost on a
per-light basis. That is to say, the more lights affecting each object, the slower rendering
performance will become. For some game types, with lots of lights, this may, therefore, be
prohibitive. However, if it is possible to manage light counts in your game, Forward Rendering can
actually be a very fast solution.
Deferred Rendering
In 'Deferred' rendering, on the other hand, we defer the shading and blending of light information
until after a first pass over the screen where positions, normals, and materials for each surface are
rendered to a ‘geometry buffer’ (G-buffer) as a series of screen-space textures. We then composite
these results together with the lighting pass. This approach has the principle advantage that the
render cost of lighting is proportional to the number of pixels that the light illuminates, instead of
the number of lights themselves. As a result, you are no longer bound by the number of lights you
wish to render on screen, and for some games, this is a critical advantage.
Deferred Rendering gives highly predictable performance characteristics but generally requires
more powerful hardware. It is also not supported by certain mobile hardware.
For more information on the Deferred, Forward and the other available rendering paths, please see
the documentation here.
Figure 08: Image comparing objects lit using Linear and Gamma Color Space. Notice how colors
quickly turn to white as light intensities increase using the Gamma Color Space.
Another main benefit of Linear is that shaders can also sample textures without Gamma (mid-tone)
compensation. This helps to ensure that color values remain consistent throughout their journey
through the render pipeline. The result is increased accuracy in color calculations with improved
overall realism in the eventual screen output.
Gamma Color Space
Unfortunately, Linear Color Space is not supported by some mobile hardware and even certain
games consoles. In these instances, Gamma must be used instead. Linear is currently supported on
PC, newer mobile hardware and current generation consoles.
It’s important to confirm that your target platform supports your selected Color Space before
proceeding.
For more information on Color Space please see the documentation here.
Tonemapping
Using the analogy of photography, if we were to photograph our scene using different exposure
settings, then we could start to see these extreme color details which otherwise might have been
lost. Light tones in the brightest areas of the image which have been lost to white can be recovered,
or dark tones lost to black. This is analogous to ‘tonemapping’ in computer graphics, where we take
colors outside of the range reproducible by our target device (computer screen, for example) and
shift them mathematically into a range that can be reproduced. The resulting output still makes
sense perceptually, because colors remain relative to one another. They are correct in context.
In order to use Tonemapping, you will need to import the Post Processing package from the
Package Manager by going to Window > Package Manager. Tonemapping provides you control
over how very bright color intensities recorded by your camera are converted into colors that can be
displayed.
More information on Tonemapping can be found here.
7.Reflections
Reflection Source
By default, objects in a scene are rendered using Unity’s ‘Standard Shader’. The Standard Shader is
a 'physically-based shader' (PBS). This attempts to accurately represent the behavior of light on
materials by mimicking physical properties such as reflectivity and the principles of ‘energy
conservation’ which exist in the real world.
When using the Standard Shader, every material has a degree of reflectivity based on its
‘specularity’, or ‘metalness’. Without hardware powerful enough to ray trace reflections in realtime
we have to rely on pre-rendering reflections. We do this with a cubemap - a 6-sided image of the
world derived either from the sky or from a ‘Reflection Probe’ which renders the environment from
a specific point in space, writing the results to a texture. This is then blended with other lighting and
surface data by a material’s shader in order to approximate the effects of reflectivity as we see in the
real world.
Figure 09: By default, highly Specular/Metal materials in your scene will reflect the Skybox,
defined by the Reflection Source property of the Environment Lighting Panel. This behavior can be
changed by choosing a different source, or by adding a Reflection Probe to your scene.
By default, objects in a Unity scene will reflect the Skybox. However, this behavior can be changed
globally in the Lighting window using the ‘Reflection Source’ property. The Skybox, or
alternatively, a custom cubemap may be used. This ‘Reflection Source’ can be thought of as a
scene-wide cubemap used by all objects in the scene unless overridden - by adding a Reflection
Probe.
Reflection Probes
Often it is undesirable for objects to simply reflect the Skybox in a Unity scene. In many instances,
objects may be blocked or ‘occluded’ from the sky. They may be indoors or underneath an
architectural feature like a bridge or tunnel. To create more accurate reflections we need to sample
what objects ‘see’ using a ‘Reflection Probe’. These probes render the world from their position in
3D space and write the results to a cubemap. This can then be used by nearby objects to give the
impression that they are reflecting the world around them.
A reflection probe can be added via GameObject > Light > Reflection Probe.
The position of a Reflection Probe will determine what the generated cubemap looks like, and
therefore what is ‘seen’ in the reflections. Generally, for performance reasons, it is better to use as
few probes as possible. Remember, reflection probes are not meant to give physically accurate
results, but instead give the impression of reflections in the game world. A few well-placed probes
throughout your scene will be sufficient in most cases.
Figure 10: Left: Our scene with default reflections. Right: With a Reflection Probe added.
In the Inspector panel for a Reflection Probe, we can set the Type property of the probe to choose
between Baked, Custom or Realtime. It should be noted that Realtime Reflection Probes are
extremely detrimental to performance as we are effectively rendering the scene an additional 6
times for each probe. There are specific cases where a realtime reflection probe is required and this
expense is justified, but as a general rule, Baked Reflection Probes are preferable as they are
considerably more performant.
Note that GameObjects are only visible to Baked Reflection Probes if marked as Reflection Probe
Static from the Static drop-down at the top of the Inspector panel. Conversely, Realtime probes
render all visible GameObjects in the world unless a culling mask is applied.
8.Ambient Lighting
An important contributor to the overall look and brightness of a scene is ‘ambient lighting’. This
can be thought of as a global light source affecting objects in the scene from every direction.
Ambient light can be useful in a number of cases, depending upon your chosen art style. An
example would be bright, cartoon-style rendering where dark shadows may be undesirable or where
lighting is perhaps hand-painted into textures. Ambient light can also be useful if you need to
increase the overall brightness of a scene without adjusting individual lights.
Without using one of Unity’s precomputed lighting solutions, ambient light will not be occluded
and therefore will not be physically accurate. However, if either Baked GI or Precomputed Realtime
GI are enabled in your scene then this ‘skylight’ will be blocked by objects in your scene - giving a
more realistic result.
Figure 11: The same scene with no light whatsoever (Left) and with only Ambient Light (Right).
Notice how the visible Skybox does not change when changes are made to the Ambient Intensity.
Figure 12: Now using Precomputed Realtime GI by marking the objects as static. Notice how light
is now occluded in areas of contact between surfaces.
A significant advantage of using ambient light is that it is cheap to render and so particularly useful
for mobile applications where perhaps it is desirable to minimize the number of lights in your scene.
Ambient Lighting can be controlled in the Lighting window from the Environment Lighting
section Window > Rendering > Lighting Settings > Source.
The default value is for the Source property to be set to Skybox. The Skybox, in this case, is the
default procedural Skybox that - with default settings - contributes a blue tint to the Ambient
Lighting of the scene. The other options for the Source include Color, which is a solid color or a
Gradient which is a simple color ramp applied over the hemisphere.
Note that changing the color of the ambient source does not affect the visible Skybox, instead it
only affects the color of lighting within the scene.
9.Light Types
We have now covered some of the project settings which need to be considered before beginning
work on lighting your scenes in Unity. Hopefully, at this point, you should have your project
configured appropriately for your target platform (generally Baked GI and Gamma Color Space for
mobile, Precomputed Realtime GI and Linear Color Space for Standalone PC or recent games
consoles).
Let’s move on to looking at the tools available for achieving the lighting you want in your game.
Directional Lights
Directional Lights are very useful for creating effects such as sunlight in your scenes. Behaving in
many ways like the sun, Directional Lights can be thought of as distant light sources which exist
infinitely far away.
Light rays emitted from Directional Lights are parallel to one another and do not diverge like those
from other light types. As a result, shadows cast by Directional Lights look the same, regardless of
their position relative to the source. This is useful to us, especially when lighting outdoor scenes.
Point Lights
A Point Light can be thought of as a point in 3D space from which light is emitted in all directions.
These are useful for creating effects like light bulbs, weapon glow or explosions where you expect
the light to radiate out from an object.
The intensity of Point Lights in Unity diminishes quadratically from the full intensity at the center
of the light, to zero at the limit of the light’s reach defined by the Range property of the component
in the Inspector. Light intensity is inversely proportional to the square of the distance from the
source. This is known as inverse square law and is similar to how light behaves in the real world.
Figure 14: Point Lights emit light in all directions from their position in the world. The spherical
gizmo represents the ‘Range’ of the Light. Direct Light will ‘Falloff’ to zero when it reaches this
limit, however, bounced - or indirect light can continue much further.
Enabling shadows for Point Lights can be expensive and so must be used sparingly. Point Lights
require that shadows have to be rendered six times for the six world directions and on slower
hardware, this can be an unacceptable performance cost.
When adding Point Lights to a scene it’s worth noting that currently, they do not support indirect
bounce light shadowing. This means that the light created by Point Lights will continue through
objects and bounce on the other side unless attenuated by range. This can lead to light ‘leaks’
through walls and floors and therefore lights must be carefully placed to avoid such problems. This,
however, is not a problem when using Baked GI.
Spotlights
Spotlights project a cone of light in their forward (+Z) direction. The width of this cone is defined
by the light’s Spot Angle parameter. Light will ‘falloff’ from the source position towards the extent
of the light’s range, where it will eventually diminish to zero. Light also diminishes at the edges of
the Spotlight’s cone. Widening the Spot Angle increases the width of the cone and with it, increases
the size of this fade, known as the ‘penumbra’.
Figure 15: Display of a spotlight
Spotlights have many useful applications for scene lighting. They can be used to great effect as
street lights, wall downlights or used dynamically, for creating effects like a flashlight. As their area
of influence can be precisely controlled, Spotlights are extremely useful for creating a focus on a
character or for creating dramatic stage lighting effects
Figure 16: Light will diminish as distance increases from the source. Notice how light also fades
towards the edges of the cone. We call this the Light’s penumbra and this increases as the angle of
the cone increases.
Like Point Lights, Spotlights do not presently support indirect shadowing when using Precomputed
Realtime GI. This means that light produced by Spotlights will travel through geometry and will
bounce on the other side. Placement, therefore, needs to be carefully considered.
Area Lights
Area Lights can be thought of as similar to a photographer’s softbox. In Unity, they are defined as
rectangles from which light is emitted in all directions, from one side only - the object’s +Z
direction. Presently only available in Baked GI, these Area Lights illuminate uniformly across their
surface area. There is no manual control for the range of an Area Light, however, the intensity will
diminish at the inverse square of the distance as it travels away from the source.
Figure 17: Light is emitted across the surface of an Area Light producing a diffuse light with soft
shadowing.
Area Lights are useful in situations where you wish to create soft lighting effects. As light is emitted
in all directions across the surface of the light, the rays produced travel in many directions - creating
a diffuse lighting effect across a subject. A common use for this might be a ceiling strip light or a
backlit panel.
In order to achieve this, we must fire a number of rays from each lightmap texel in the world, back
towards the light in order to determine whether the light can be seen. This means that Area Lights
can be quite computationally expensive and can increase bake times. However, used well, they can
add a great depth of realism to your scene lighting and this extra precomputation may be justified.
Note that as they are baked only, gameplay performance is not affected.
10.Emissive Materials
Whilst Area Lights are not supported by Precomputed Realtime GI, similar soft lighting effects are
still possible using Emissive Materials. Like Area Lights, emissive materials emit light across their
surface area. They contribute to bounced light in your scene and associated properties such as color
and intensity can be changed during gameplay.
Emission is a property of the Standard Shader which allows static objects in our scene to emit light.
By default, the value of Emission is set to zero. This means no light will be emitted by objects
assigned materials using the Standard Shader. The HDR color picker can be used to select colors
with intensities beyond the 0-1 range in order to create bright light effects similar to those of Area
Lights.
There is no range value for emissive materials but the light emitted will again falloff at a quadratic
rate. The emission will only be received by objects marked as Static or Lightmap Static from the
Inspector. Similarly, emissive materials applied to non-static, or dynamic geometry such as
characters will not contribute to scene lighting.
However, materials with emission above zero will still appear to glow brightly on-screen even if
they are not contributing to scene lighting. This effect can also be produced by selecting None from
the Standard Shader’s Global Illumination Inspector property. Self-illuminating materials like
these are a useful way to create effects such as neons or other visible light sources.
Figure 18: Simple neon sign created using the ‘Emission’ property of Unity’s Standard Shader.
Notice how the emission from the sign is still shadowed by static geometry - in this case, the sphere.
Emissive materials only directly affect static geometry in your scene. If you need dynamic, or non-
static geometry - such as characters, to pick up light from emissive materials, Light Probes must be
used. Changing emission values at gameplay will update Light Probes interactively and the results
will be visible on any objects presently receiving light from those probes.
11.Light Probes
Only static objects are considered by Unity’s Baked or Precomputed Realtime GI systems. In order
for dynamic objects such as interactive scene elements or characters to pick up some of the rich
bounced light that our static geometry receives, we need to record this lighting information into a
format that can be quickly read and used in our lighting equations during gameplay.
We do this by placing sample points in the world and then capturing light from all directions. The
color information these points record is then encoded into a set of values (or ‘coefficients’) which
can be quickly evaluated during gameplay. In Unity, we call these sample points, ‘Light Probes’.
Figure 19: Scene using Light Probes. Notice how they have been placed in greater density around
areas of lighting change - such as shadows or color transition.
Light Probes allow moving objects to respond to the same complex bounced lighting which is
affecting our lightmaps regardless of whether Baked GI or Precomputed Realtime GI is used. An
object’s mesh renderer will look for the Light Probes around its position and blend between their
values. This is done by looking for tetrahedrons made up by the position of Light Probes, and then
deciding which tetrahedron the object’s pivot falls into. This allows us to place moving characters in
scenes and have them appear properly integrated. Without Light Probes, dynamic objects would not
receive any global illumination and would appear darker than surrounding, lightmapped geometry.
By default there are no Light Probes in a scene so these will need to be placed using a Light Probe
Group GameObjects > Light > Light Probe Group.
If the ‘Auto’ box is checked at the bottom of your scene precompute settings Window > Rendering
> Lighting Settings > Auto Generate, Light Probes will update whenever changes are made to the
scene lighting or static geometry. Otherwise, they will be updated when the Build button is clicked.
12.Next Steps
In this tutorial, we have given an overview of the considerations which need to be made prior to
setting up a scene for lighting. We have also briefly looked at the tools available for creating various
lighting effects. However, there is still a lot that we haven’t yet covered. For a more in-depth look at
optimizing your Scenes for Unity's Precomputed Realtime GI, please see our tutorial here.
English
简体中文
한국어
日本語
Русский
Español
Français
Deutsch
Português