Lighting in Unity
Lighting in Unity tutorials
Verbatim extracts from https://learn.unity.com/tutorial/introduction-to-lighting-and-rendering#5c7f8528edbc2a002053b528
Global illumination, or ‘GI’, is a term used to describe a
range of techniques and mathematical models which attempt to simulate the
complex behaviour of light as it bounces and interacts with the world.
Simulating global illumination accurately is challenging and can be
computationally expensive. Because of this, games use a range of approaches to
handle these calculations beforehand, rather than during gameplay
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.
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
which are overlaid on top of scene geometry to create the effect of lighting.
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 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.
Precomputed Realtime GI Lighting
Whilst traditional, static lightmaps are unable to react to
changes in lighting conditions within the scene, Precomputed Realtime GI does
offer us a technique for updating complex scene lighting interactively.
With this approach it is possible to create lit environments featuring rich global illumination with bounced light which responds, in realtime, to lighting changes. A good example of this would be a time of day system - where the position and color of the light source changes over time. With traditional baked lighting, this is not possible.
simple example of time of day using Precomputed Realtime GI.
In order to deliver these effects at playable framerates, we
need to shift some of the lengthy number-crunching from being a realtime
process, to one which is ‘precomputed’.
Precomputing shifts the burden of calculating complex light
behaviour from something that happens during gameplay, to something which can
be calculated when time is no longer so critical. We refer to this as an
‘offline’ process.
So how does this work?
Most frequently it is indirect (bounced) light that we want
to store in our lightmaps when trying to create realism in our scene lighting.
Fortunately, this tends to be soft with few sharp, or 'high frequency’ changes
in color. Unity’s Precomputed Realtime GI solution exploits these ‘diffuse’
characteristics of indirect light to our advantage.
Finer lighting details, such as crisp shadowing, are usually
better generated with realtime lights rather than baking them into lightmaps.
By assuming we don’t need to capture these intricate details we can greatly
reduce the resolution of our global illumination solution.
By making this simplification during the precompute, we
effectively reduce the number of calculations we need to make in order to
update our GI lighting during gameplay. This is important if we were to change
properties of our lights - such as color, rotation or intensity, or even make
change to surfaces in the scene.
To speed up the precompute further Unity doesn’t directly work on lightmaps texels, but instead creates a low resolution approximation of the static geometry in the world, called ‘clusters’.
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
framerates. 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 is 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.
Enabling Baked GI or Precomputed Realtime GI
By default, both Precomputed Realtime GI and Baked GI are
enabled in Unity’s Lighting panel (Lighting>Scene). With both enabled, which
technique is used can then be controlled by each light individually
(Inspector>Light>Baking).
Using both Baked GI and Precomputed Realtime GI together in
your scene can be detrimental to performance. A good practise is to ensure that
only one system is used at a time, by disabling the other globally. This can be
done by unchecking the box next to either Precomputed Realtime GI or Baked GI
from Unity’s lighting panel (Lighting>Scene). Now only the checked option
will be present in your scene, and any settings configured per-light will be
overridden.
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.
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 onto
lightmapped geometry.
The Precompute Process
In Unity, precomputed lighting is calculated in the
background - either as an automatic process, or it is initiated manually. In
either case, it is possible to continue working in the editor while these
processes run behind-the-scenes.
When the precompute process is running, a blue progress bar
will appear in the bottom right of the Editor. There are different stages which
need to be completed depending on whether Baked GI or Precomputed Realtime GI
is enabled. Information on the current process is shown on-top of the progress
bar.
In the example above, we can see that we are at task 5 of 11
which is, ‘Clustering’ and there are 108 jobs remaining before that task is
complete and the precompute moves on to task 6. The various stages are listed
below:
Precomputed Realtime GI Baked
GI
01 - Create Geometry
01 - Create Geometry
02 - Layout Systems 02
- Atlassing
03 - Create Systems 03
- Create Baked Systems
04 - Create Atlas 04
- Baked Resources
05 - Clustering 05
- Bake AO
06 - Visibility 06
- Export Baked Texture
07 - Light Transport 07
- Bake Visibility
08 - Tetrahedralize Probes 08
- Bake Direct
09 - Create ProbeSet 09
- Ambient and Emissive
10 - Create Bake Systems
Probes 11
- Bake Runtime
12 - Upsampling Visibility
01 - Ambient Probes 13
- Bake Indirect
02 - Baked/Realtime Ref. Probes 14 - Final Gather
15 - Bake ProbesSet
16 - Compositing
<p> </p>
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 precompute 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 (Lighting>Scene>Auto), 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 ‘Build’ 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 via
the drop-down menu next to the Build button (Lighting>Scene>Build).
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 precompute. 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.
Comments
Post a Comment