Revamp global illumination documentation
- Add an introduction page with an explanation and comparison table. - Add a page on faking global illumination.
@@ -23,6 +23,8 @@ your texture to display correctly on all platforms, you should avoid using
|
||||
textures larger than 4096×4096 and use a power of two size if the texture needs
|
||||
to repeat.
|
||||
|
||||
.. _doc_3d_rendering_limitations_color_banding:
|
||||
|
||||
Color banding
|
||||
-------------
|
||||
|
||||
|
||||
@@ -1,378 +0,0 @@
|
||||
.. _doc_baked_lightmaps:
|
||||
|
||||
Baked lightmaps
|
||||
===============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Baked lightmaps are an alternative workflow for adding indirect (or fully baked)
|
||||
lighting to a scene. Unlike the :ref:`doc_gi_probes` approach, baked lightmaps
|
||||
work fine on low-end PCs and mobile devices, as they consume almost no resources
|
||||
at run-time. Also unlike GIProbe, baked lightmaps can optionally be used to
|
||||
store direct lighting, which provides even further performance gains.
|
||||
|
||||
Unlike GIProbes, Baked Lightmaps are completely static. Once baked, they
|
||||
can't be modified at all. They also don't provide the scene with reflections, so
|
||||
using :ref:`doc_reflection_probes` together with it on interiors (or using a Sky
|
||||
on exteriors) is a requirement to get good quality.
|
||||
|
||||
As they are baked, they have fewer problems than ``GIProbe`` regarding light
|
||||
bleeding, and indirect light will often look better. The downside is that baking
|
||||
lightmaps takes much longer than baking a GIProbe. While baking a GIProbe can be
|
||||
done in a matter of seconds, baking lightmaps will take several minutes if not
|
||||
more. This can slow down iteration speed significantly, so it is recommended to
|
||||
bake lightmaps only when you actually need to see changes in lighting.
|
||||
|
||||
Baking lightmaps will also reserve baked materials' UV2 slot, which means you can
|
||||
no longer use it for other purposes in materials (either in the built-in
|
||||
:ref:`doc_standard_material_3d` or in custom shaders).
|
||||
|
||||
In the end, deciding which indirect lighting approach is better depends on your
|
||||
use case. In general, GIProbe is easier to set up and works better with dynamic
|
||||
objects. For mobile or low-end compatibility, though, baked lightmaps are your
|
||||
only choice.
|
||||
|
||||
Visual comparison
|
||||
-----------------
|
||||
|
||||
Here are some comparisons of how BakedLightmap vs. GIProbe look. Notice that
|
||||
lightmaps are more accurate, but also suffer from the fact
|
||||
that lighting is on an unwrapped texture, so transitions and resolution may not
|
||||
be that good. GIProbe looks less accurate (as it's an approximation), but
|
||||
smoother overall.
|
||||
|
||||
.. image:: img/baked_light_comparison.png
|
||||
|
||||
Setting up
|
||||
----------
|
||||
|
||||
First of all, before the lightmapper can do anything, the objects to be baked need
|
||||
an UV2 layer and a texture size. An UV2 layer is a set of secondary texture coordinates
|
||||
that ensures any face in the object has its own place in the UV map. Faces must
|
||||
not share pixels in the texture.
|
||||
|
||||
There are a few ways to ensure your object has a unique UV2 layer and texture size:
|
||||
|
||||
Unwrap on scene import
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This is probably the best approach overall. The only downside is that, on large
|
||||
models, unwrapping can take a while on import. Nonetheless, Godot will cache the UV2
|
||||
across reimports, so it will only be regenerated when needed.
|
||||
|
||||
Select the imported scene in the filesystem dock, then go to the **Import** dock.
|
||||
There, the following option can be modified:
|
||||
|
||||
.. image:: img/baked_light_import.png
|
||||
|
||||
The **Light Baking** mode needs to be set to **Gen Lightmaps**. A texel size
|
||||
in world units must also be provided, as this will determine the
|
||||
final size of the lightmap texture (and, in consequence, the UV padding in the map).
|
||||
|
||||
The effect of setting this option is that all meshes within the scene will have
|
||||
their UV2 maps properly generated.
|
||||
|
||||
.. warning::
|
||||
|
||||
When reusing a mesh within a scene, keep in mind that UVs will be generated
|
||||
for the first instance found. If the mesh is re-used with different scales
|
||||
(and the scales are wildly different, more than half or twice), this will
|
||||
result in inefficient lightmaps. Don't reuse a source mesh at significantly
|
||||
different scales if you are planning to use lightmapping.
|
||||
|
||||
Also, the ``*.unwrap_cache`` files should *not* be ignored in version control
|
||||
as these files guarantee that UV2 reimports are consistent across platforms
|
||||
and engine versions.
|
||||
|
||||
Unwrap from within Godot
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Godot has an option to unwrap meshes and visualize the UV channels.
|
||||
It can be found in the Mesh menu:
|
||||
|
||||
.. image:: img/baked_light_mesh_menu.png
|
||||
|
||||
This will generate a second set of UV2 coordinates which can be used for baking,
|
||||
and it will also set the texture size automatically.
|
||||
|
||||
Unwrap from your 3D DCC
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The last option is to do it from your favorite 3D app. This approach is generally
|
||||
not recommended, but it's explained first so that you know it exists.
|
||||
The main advantage is that, on complex objects that you may want to re-import a
|
||||
lot, the texture generation process can be quite costly within Godot,
|
||||
so having it unwrapped before import can be faster.
|
||||
|
||||
Simply do an unwrap on the second UV2 layer.
|
||||
|
||||
.. image:: img/baked_light_blender.png
|
||||
|
||||
Then import the 3D scene normally. Remember you will need to set the texture
|
||||
size on the mesh after import.
|
||||
|
||||
.. image:: img/baked_light_lmsize.png
|
||||
|
||||
If you use external meshes on import, the size will be kept.
|
||||
Be wary that most unwrappers in 3D DCCs are not quality oriented, as they are
|
||||
meant to work quickly. You will mostly need to use seams or other techniques to
|
||||
create better unwrapping.
|
||||
|
||||
Checking UV2
|
||||
~~~~~~~~~~~~
|
||||
|
||||
In the mesh menu mentioned before, the UV2 texture coordinates can be visualized.
|
||||
Make sure, if something is failing, to check that the meshes have these UV2 coordinates:
|
||||
|
||||
.. image:: img/baked_light_uvchannel.png
|
||||
|
||||
Setting up the scene
|
||||
--------------------
|
||||
|
||||
Before anything is done, a **BakedLightmap** node needs to be added to a scene.
|
||||
This will enable light baking on all nodes (and sub-nodes) in that scene, even
|
||||
on instanced scenes.
|
||||
|
||||
.. image:: img/baked_light_scene.png
|
||||
|
||||
A sub-scene can be instanced several times, as this is supported by the baker, and
|
||||
each will be assigned a lightmap of its own (just make sure to respect the rule
|
||||
about scaling mentioned before):
|
||||
|
||||
Configure bounds
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Lightmap needs an approximate volume of the area affected because it uses it to
|
||||
transfer light to dynamic objects inside it (more on that later). Just
|
||||
cover the scene with the volume as you do with ``GIProbe``:
|
||||
|
||||
.. image:: img/baked_light_bounds.png
|
||||
|
||||
Setting up meshes
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
For a **MeshInstance3D** node to take part in the baking process, it needs to have
|
||||
the **Use in Baked Light** property enabled.
|
||||
|
||||
.. image:: img/baked_light_use.png
|
||||
|
||||
When auto-generating lightmaps on scene import, this is enabled automatically.
|
||||
|
||||
Setting up lights
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Lights are baked with indirect light by default. This means that shadowmapping
|
||||
and lighting are still dynamic and affect moving objects, but light bounces from
|
||||
that light will be baked.
|
||||
|
||||
Lights can be disabled (no bake) or be fully baked (direct and indirect). This
|
||||
can be controlled from the **Bake Mode** menu in lights:
|
||||
|
||||
.. image:: img/baked_light_bake_mode.png
|
||||
|
||||
The modes are:
|
||||
|
||||
Disabled
|
||||
^^^^^^^^
|
||||
|
||||
The light is ignored when baking lightmaps. Keep in mind hiding a light will have
|
||||
no effect for baking, so this must be used instead of hiding the Light node.
|
||||
|
||||
This is the mode to use for dynamic lighting effects such as explosions and weapon effects.
|
||||
|
||||
Indirect
|
||||
^^^^^^^^
|
||||
|
||||
This is the default mode, and is a compromise between performance and real-time
|
||||
friendliness. Only indirect lighting will be baked. Direct light and shadows are
|
||||
still real-time, as they would be without BakedLightmap.
|
||||
|
||||
This mode allows performing *subtle* changes to a light's color, energy and
|
||||
position while still looking fairly correct. For example, you can use this
|
||||
to create flickering static torches that have their indirect light baked.
|
||||
|
||||
All
|
||||
^^^
|
||||
|
||||
Both indirect and direct lighting will be baked. Since static surfaces can skip
|
||||
lighting and shadow computations entirely, this mode provides the best
|
||||
performance along with smooth shadows that never fade based on distance. The
|
||||
real-time light will not affect baked surfaces anymore, but it will still affect
|
||||
dynamic objects. When using the **All** bake mode on a light, dynamic objects
|
||||
will not cast real-time shadows onto baked surfaces, so you need to use a
|
||||
different approach such as blob shadows instead. Blob shadows can be implemented
|
||||
with a Sprite3D + RayCast setup, or a negative SpotLight pointing down with its
|
||||
bake mode set to **Disabled**.
|
||||
|
||||
The light will not be adjustable at all during gameplay. Moving
|
||||
the light and changing its color or energy will not have any effect on static surfaces.
|
||||
|
||||
Since bake modes can be adjusted on a per-light basis, it is possible to create
|
||||
hybrid baked light setups. One popular option is to use a real-time
|
||||
DirectionalLight with its bake mode set to **Indirect**, and use the **All**
|
||||
bake mode for OmniLights and SpotLights. This provides good performance while
|
||||
still allowing dynamic objects to cast real-time shadows in outdoor areas.
|
||||
|
||||
After selecting the **All** bake mode on a light, you can optionally
|
||||
specify a **Size** greater than 0 for the light in the inspector.
|
||||
This size is used to provide softer shadows depending on the distance between
|
||||
the shadow caster and the object receiving the shadow. This mimics real life
|
||||
shadow appearance:
|
||||
|
||||
.. image:: img/baked_light_omnilight_size.png
|
||||
|
||||
The light's **Size** property is ignored for real-time shadows; it will only affect baked
|
||||
shadows. When the **Size** property is changed, lightmaps must be baked again to
|
||||
make changes visible.
|
||||
|
||||
Baking
|
||||
------
|
||||
|
||||
To begin the bake process, just push the **Bake Lightmaps** button on top
|
||||
when selecting the BakedLightmap node:
|
||||
|
||||
.. image:: img/baked_light_bake.png
|
||||
|
||||
This can take from seconds to minutes (or hours) depending on scene size, bake
|
||||
method and quality selected.
|
||||
|
||||
Balancing bake times with quality
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Since high-quality bakes can take very long (up to several hours for large complex scenes),
|
||||
it is recommended to use lower quality settings at first. Then, once you are confident
|
||||
with your scene's lighting setup, raise the quality settings and perform a "final"
|
||||
bake before exporting your project.
|
||||
|
||||
.. note::
|
||||
|
||||
By default, the lightmap baker will use all the system's logical CPU cores
|
||||
to speed up baking. This can reduce system responsiveness. To preserve system
|
||||
responsiveness while lightmaps are baking, you can reduce the number of CPU threads
|
||||
used to bake lightmaps. Keeping 1 or 2 CPU threads free will help improve
|
||||
system responsiveness, which is useful when multi-tasking while lightmaps are
|
||||
baking at the cost of slowing down lightmap baking slightly.
|
||||
|
||||
To do so, open **Editor > Editor Settings** and adjust
|
||||
**Editors > 3d > Lightmap Baking Number Of Cpu Threads**.
|
||||
The default value (``0``) uses all of the system's logical CPU cores.
|
||||
Positive values will specify a number of threads to use, while negative
|
||||
values will subtract from the total number of logical CPU cores in the system.
|
||||
For example, on a system with 8 logical CPU cores, adjusting the setting to
|
||||
``-1`` will use 7 CPU threads for lightmap baking.
|
||||
|
||||
Configuring bake
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Several more options are present for baking:
|
||||
|
||||
- **Bake Extents**: The size of the area affected. This can be edited in the 3D
|
||||
editor viewport using the handles. Any object that can have lightmaps baked and
|
||||
is *touching* the bake extents will have lightmaps baked for it, but dynamic
|
||||
object capture will only work within the extents.
|
||||
|
||||
Tweaks
|
||||
^^^^^^
|
||||
|
||||
- **Quality:** Four bake quality modes are provided: Low, Medium, High, and Ultra.
|
||||
Higher quality takes more time, but result in a better-looking lightmap with
|
||||
less noise. The difference is especially noticeable with emissive materials or
|
||||
areas that get little to no direct lighting.
|
||||
- **Bounces:** The number of bounces to use for indirect lighting. The default value (3)
|
||||
is a good compromise between bake times and quality. Higher values will make
|
||||
light bounce around more times before it stops, which makes indirect lighting
|
||||
look smoother (but also brighter). During the initial lighting iteration work,
|
||||
it is recommended to decrease the number of bounces to 1 to speed up baking.
|
||||
Remember that your scene will be darker when decreasing the number of bounces.
|
||||
- **Use Denoiser:** If enabled, uses OpenImageDenoise to make the lightmap
|
||||
significantly less noisy. This increases bake times and can occasionally
|
||||
introduce artifacts, but the result is often worth it.
|
||||
- **Use Hdr:** If disabled, lightmaps are smaller on disk, but they won't be
|
||||
able to capture any light over white (1.0). This will result in visible clipping
|
||||
if you have bright lights in your scene. When HDR is disabled, banding may also
|
||||
be visible in the lightmap.
|
||||
- **Use Color:** If disabled, lightmaps are smaller on disk, but the lightmap
|
||||
won't be able to store colored lighting. When baking indirect light only, the
|
||||
difference may be barely visible since indirect light is generally not highly
|
||||
saturated. However, when baking both direct and indirect lighting using the
|
||||
**All** bake mode on a light, this will turn colored lighting into grayscale
|
||||
lighting. This can be disabled together with HDR to get the smallest possible
|
||||
lightmap file at a given resolution.
|
||||
- **Bias:** The offset value to use for shadows in 3D units. You generally don't
|
||||
need to change this value, except if you run into issues with light bleeding or
|
||||
dark spots in your lightmap after baking. This setting does not affect real-time
|
||||
shadows casted on baked surfaces.
|
||||
- **Default Texels Per Unit:** For meshes that do not specify their own lightmap
|
||||
texel density, this will be used as the value. Higher values result in
|
||||
*lower-resolution* lightmaps, which result in faster bake times and lower file
|
||||
sizes at the cost of blurrier indirect lighting and shadows.
|
||||
|
||||
Atlas
|
||||
^^^^^
|
||||
|
||||
- **Generate:** If enabled, a texture atlas will be generated for the lightmap.
|
||||
This results in more efficient rendering, but is only compatible with the
|
||||
GLES3 rendering backend. Disable this setting if your project is allowed to
|
||||
fall back to GLES2. (This is not the case by default and must be enabled in
|
||||
the Project Settings.) *This setting is ignored when the project is configured
|
||||
to use GLES2 by default.*
|
||||
- **Max Size:** The maximum size of the atlas in pixels. Higher values result
|
||||
in a more efficient atlas, but are less compatible with old/low-end hardware.
|
||||
If in doubt, leave this setting on its default value (4096).
|
||||
|
||||
Capture
|
||||
^^^^^^^
|
||||
|
||||
- **Enabled:** This enables probe capture so that dynamic objects can *receive* indirect lighting.
|
||||
Regardless of this setting's value, dynamic objects will not be able to
|
||||
*contribute* indirect lighting to the scene. This is a limitation of lightmaps.
|
||||
- **Cell Size:** The distance between lightmap probes in 3D units. Higher values
|
||||
result in more sparse probe placement, which decreases bake times and file
|
||||
size at the cost of lower lighting accuracy for dynamic objects.
|
||||
- **Quality:** The lightmap probe generation quality. Higher values result in
|
||||
more accurate lighting, but take longer to bake. This setting does not affect
|
||||
the *density* of the lightmap probes, only their quality.
|
||||
- **Propagation:** Similar to :ref:`GIProbe <doc_gi_probes>`'s Propagation property.
|
||||
Higher values result in brighter and more diffuse indirect lighting for
|
||||
dynamic objects. Adjust this value depending on your scene to make dynamic
|
||||
objects better fit with static baked lighting.
|
||||
|
||||
Data
|
||||
^^^^
|
||||
|
||||
- **Light Data**: Contains the light baked data after baking. Textures are saved
|
||||
to disk, but this also contains the capture data for dynamic objects, which can
|
||||
be heavy. If you are using a scene in ``.tscn`` format, you should save this
|
||||
resource to an external binary ``.lmbake`` file to avoid bloating the ``.tscn``
|
||||
scene with binary data encoded in Base64.
|
||||
|
||||
The Light Data resource can be edited to adjust two additional properties:
|
||||
|
||||
- **Energy:** Adjusts the lightmap's brightness. Higher values result in brighter lightmaps.
|
||||
This can be adjusted at run-time for short-lived dynamic effects such as thunderstorms.
|
||||
However, keep in mind that it will affect *all* baked lights.
|
||||
- **Interior:** If enabled, dynamic objects will not make use of environment lighting
|
||||
and will use light probes for ambient lighting exclusively. If disabled, both
|
||||
environment lighting and light probes are used to light up dynamic objects.
|
||||
|
||||
.. tip::
|
||||
|
||||
The generated EXR file can be viewed and even edited using an image editor
|
||||
to perform post-processing if needed. However, keep in mind that changes to
|
||||
the EXR file will be lost when baking lightmaps again.
|
||||
|
||||
Dynamic objects
|
||||
---------------
|
||||
|
||||
In other engines or lightmapper implementations, you are generally required to
|
||||
manually place small objects called "lightprobes" all around the level to
|
||||
generate *capture* data. This is then used to transfer the light to dynamic
|
||||
objects that move around the scene.
|
||||
|
||||
However, this implementation of lightmapping uses a different method. The process is
|
||||
automatic, so you don't have to do anything. Just move your objects around, and
|
||||
they will be lit accordingly. Of course, you have to make sure you set up your
|
||||
scene bounds accordingly or it won't work.
|
||||
|
||||
.. image:: img/baked_light_indirect.gif
|
||||
100
tutorials/3d/faking_global_illumination.rst
Normal file
@@ -0,0 +1,100 @@
|
||||
.. _doc_faking_global_illumination:
|
||||
|
||||
Faking global illumination
|
||||
==========================
|
||||
|
||||
Why fake global illumination?
|
||||
-----------------------------
|
||||
|
||||
Godot provides several global illumination (GI) techniques, all with their advantages
|
||||
and drawbacks. Nonetheless, it remains possible to avoid using any GI technique
|
||||
and use a handmade approach instead. There are a few reasons for using a
|
||||
"handmade" approach to global illumination instead of VoxelGI, SDFGI or
|
||||
baked lightmaps:
|
||||
|
||||
- You need to have good rendering performance, but can't afford going through
|
||||
a potentially cumbersome lightmap baking process.
|
||||
- You need an approach to GI that is fully real-time *and* works in procedurally
|
||||
generated levels.
|
||||
- You need an approach to GI that is fully real-time *and* does not suffer from
|
||||
significant light leaks.
|
||||
|
||||
The approaches described below only cover indirect diffuse lighting, not
|
||||
specular lighting. For specular lighting, consider using ReflectionProbes which
|
||||
are usually cheap enough to be used in conjunction with this fake GI approach.
|
||||
|
||||
.. seealso::
|
||||
|
||||
Not sure if faking global illumination with lights is suited to your needs?
|
||||
See :ref:`doc_introduction_to_global_illumination_comparison` for a
|
||||
comparison of GI techniques available in Godot 4.
|
||||
|
||||
Faking DirectionalLight3D global illumination
|
||||
---------------------------------------------
|
||||
|
||||
While the sky provides its own directional lighting, the scene's main DirectionalLight3D
|
||||
node typically emits a large amount of light. When using a GI technique, this light
|
||||
would be reflected on solid surfaces and would bounce back on most outdoors shaded surfaces.
|
||||
|
||||
We can fake this by adding a second DirectionalLight3D node with the following changes:
|
||||
|
||||
- Rotate the light by 180 degrees. This allows it to represent lighting bounced
|
||||
by the main DirectionalLight3D node.
|
||||
- Set **Shadows** to **Off**. This reduces the secondary light's performance burden
|
||||
while also allowing shaded areas to receive *some* lighting (which is what we want here).
|
||||
- Set **Energy** to 10-40% of the original value. There is no "perfect" value,
|
||||
so experiment with various energy values depending on the light and your typical
|
||||
material colors.
|
||||
- Set **Specular** to ``0.0``. Indirect lighting shouldn't emit visible specular
|
||||
lobes, so we need to disable specular lighting entirely for the secondary light.
|
||||
|
||||
.. note::
|
||||
|
||||
This approach works best in scenes that are mostly outdoors. When going indoors,
|
||||
the secondary DirectionalLight3D's light will still be visible as this light
|
||||
has shadows disabled.
|
||||
|
||||
This can be worked around by smoothly decreasing the secondary DirectionalLight3D's
|
||||
energy when entering an indoor area (and doing the opposite when leaving the indoor area).
|
||||
For instance, this can be achieved using an Area3D node and AnimationPlayer.
|
||||
|
||||
Faking positional light global illumination
|
||||
-------------------------------------------
|
||||
|
||||
It's possible to follow the same approach as DirectionalLight3D for positional
|
||||
lights (OmniLight3D and SpotLight3D). However, this will require more manual
|
||||
work as this operation needs to be repeated for every positional light node in
|
||||
the scene to look good.
|
||||
|
||||
In an ideal scenario, additional OmniLight3Ds should be added at every location
|
||||
where a significant amount of light hits a bright enough surface. However, due
|
||||
to time constraints, this isn't always easily feasible (especially when
|
||||
performing procedural level generation).
|
||||
|
||||
If you're in a hurry, you can place a secondary OmniLight3D node at the same position
|
||||
as the main OmniLight3D node.
|
||||
You can add this node as a child of the main OmniLight3D node to make it easy to
|
||||
move and hide both nodes at the same time.
|
||||
|
||||
In the secondary OmniLight3D node, perform the following changes:
|
||||
|
||||
- Increase the light's **Range** by 25-50%. This allows the secondary light to lighten
|
||||
what was previously not lit by the original light.
|
||||
- Set **Shadows** to **Off**. This reduces the secondary light's performance burden
|
||||
while also allowing shaded areas to receive *some* lighting (which is what we want here).
|
||||
- Set **Energy** to 10-40% of the original value. There is no "perfect" value,
|
||||
so experiment with various energy values depending on the light and its surroundings.
|
||||
- Set **Specular** to 0. Indirect lighting shouldn't emit visible specular lobes,
|
||||
so we need to disable specular lighting entirely for the secondary light.
|
||||
|
||||
For SpotLight3D, the same trick can be used. In this case, the secondary OmniLight3D
|
||||
should be placed in a way that reflects where *most* light will be bounced.
|
||||
This is usually close to the SpotLight3D's primary impact location.
|
||||
|
||||
In the example below, a SpotLight3D node is used to light up the room's floor.
|
||||
However, since there is no indirect lighting, the rest of the room remains
|
||||
entirely dark. In real life, the room's walls and ceiling would be lit up by
|
||||
light bouncing around. Using an OmniLight3D node positioned between the
|
||||
SpotLight3D's origin and the floor allows simulating this effect:
|
||||
|
||||
.. image:: img/faking_global_illumination_comparison.webp
|
||||
@@ -1,134 +0,0 @@
|
||||
.. _doc_gi_probes:
|
||||
|
||||
Using GIProbe
|
||||
=============
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
.. note:: This feature is only available when using the GLES3 backend.
|
||||
:ref:`doc_baked_lightmaps` can be used as an alternative
|
||||
when using the GLES2 renderer.
|
||||
|
||||
Just like with :ref:`doc_reflection_probes`, and as stated in
|
||||
the :ref:`doc_standard_material_3d`, objects can show reflected or diffuse light.
|
||||
GI Probes are similar to Reflection Probes, but they use a different and more
|
||||
complex technique to produce indirect light and reflections.
|
||||
|
||||
The strength of GI Probes is real-time, high quality, indirect light. While the
|
||||
scene needs a quick pre-bake for the static objects that
|
||||
will be used, lights can be added, changed or removed, and this will be updated
|
||||
in real-time. Dynamic objects that move within one of these
|
||||
probes will also receive indirect lighting from the scene automatically.
|
||||
|
||||
Just like with ``ReflectionProbe``, ``GIProbe`` can be blended (in a bit more limited
|
||||
way), so it is possible to provide full real-time lighting
|
||||
for a stage without having to resort to lightmaps.
|
||||
|
||||
The main downsides of ``GIProbe`` are:
|
||||
|
||||
- A small amount of light leaking can occur if the level is not carefully designed. This must be artist-tweaked.
|
||||
- Performance requirements are higher than for lightmaps, so it may not run properly in low-end integrated GPUs (may need to reduce resolution).
|
||||
- Reflections are voxelized, so they don't look as sharp as with ``ReflectionProbe``. However, in exchange they are volumetric, so any room size or shape works for them. Mixing them with Screen Space Reflection also works well.
|
||||
- They consume considerably more video memory than Reflection Probes, so they must be used with care in the right subdivision sizes.
|
||||
|
||||
Setting up
|
||||
----------
|
||||
|
||||
Just like a ``ReflectionProbe``, simply set up the ``GIProbe`` by wrapping it around
|
||||
the geometry that will be affected.
|
||||
|
||||
.. image:: img/giprobe_wrap.png
|
||||
|
||||
Afterwards, make sure to enable the **Use In Baked Light** property on the geometry instances
|
||||
in the inspector. This is required for ``GIProbe`` to recognize objects,
|
||||
otherwise they will be ignored:
|
||||
|
||||
.. image:: img/giprobe_bake_property.png
|
||||
|
||||
Once the geometry is set up, push the Bake button that appears on the 3D editor
|
||||
toolbar to begin the pre-baking process:
|
||||
|
||||
.. image:: img/giprobe_bake.png
|
||||
|
||||
.. warning::
|
||||
|
||||
Meshes should have sufficiently thick walls to avoid light leaks (avoid
|
||||
one-sided walls). For interior levels, enclose your level geometry in a
|
||||
sufficiently large box and bridge the loops to close the mesh.
|
||||
|
||||
Adding lights
|
||||
-------------
|
||||
|
||||
Unless there are materials with emission, ``GIProbe`` does nothing by default.
|
||||
Lights need to be added to the scene to have an effect.
|
||||
|
||||
The effect of indirect light can be viewed quickly (it is recommended you turn
|
||||
off all ambient/sky lighting to tweak this, though, as shown below):
|
||||
|
||||
.. image:: img/giprobe_indirect.png
|
||||
|
||||
In some situations, though, indirect light may be too weak. Lights have an
|
||||
indirect multiplier to tweak this:
|
||||
|
||||
.. image:: img/giprobe_light_indirect.png
|
||||
|
||||
And, as ``GIProbe`` lighting updates in real-time, this effect is immediate:
|
||||
|
||||
.. image:: img/giprobe_indirect_energy_result.png
|
||||
|
||||
Reflections
|
||||
-----------
|
||||
|
||||
For very metallic materials with low roughness, it's possible to appreciate
|
||||
voxel reflections. Keep in mind that these have far less detail than Reflection
|
||||
Probes or Screen Space Reflections, but fully reflect volumetrically.
|
||||
|
||||
.. image:: img/giprobe_voxel_reflections.png
|
||||
|
||||
``GIProbe``\ s can be easily mixed with Reflection Probes and Screen Space Reflections,
|
||||
as a full 3-stage fallback-chain. This allows to have precise reflections where needed:
|
||||
|
||||
.. image:: img/giprobe_ref_blending.png
|
||||
|
||||
Interior vs exterior
|
||||
--------------------
|
||||
|
||||
GI Probes normally allow mixing with lighting from the sky. This can be disabled
|
||||
when turning on the *Interior* setting.
|
||||
|
||||
.. image:: img/giprobe_interior_setting.png
|
||||
|
||||
The difference becomes clear in the image below, where light from the sky goes
|
||||
from spreading inside to being ignored.
|
||||
|
||||
.. image:: img/giprobe_interior.png
|
||||
|
||||
As complex buildings may mix interiors with exteriors, combining GIProbes
|
||||
for both parts works well.
|
||||
|
||||
Tweaking
|
||||
--------
|
||||
|
||||
GI Probes support a few parameters for tweaking:
|
||||
|
||||
.. image:: img/giprobe_tweaking.png
|
||||
|
||||
- **Subdiv** Subdivision used for the probe. The default (128) is generally good for small- to medium-sized areas. Bigger subdivisions use more memory.
|
||||
- **Extents** Size of the probe. Can be tweaked from the gizmo.
|
||||
- **Dynamic Range** Maximum light energy the probe can absorb. Higher values allow brighter light, but with less color detail.
|
||||
- **Energy** Multiplier for all the probe. Can be used to make the indirect light brighter (although it's better to tweak this from the light itself).
|
||||
- **Propagation** How much light propagates through the probe internally.
|
||||
- **Bias** Value used to avoid self-occlusion when doing voxel cone tracing, should generally be above 1.0 (1==voxel size).
|
||||
- **Normal Bias** Alternative type of bias useful for some scenes. Experiment with this one if regular bias does not work.
|
||||
- **Interior** Allows mixing with lighting from the sky.
|
||||
- **Compress** Currently broken. Do not use.
|
||||
- **Data** Contains the light baked data after baking. If you are saving the data it should be saved as a .res file.
|
||||
|
||||
Quality
|
||||
-------
|
||||
|
||||
``GIProbe``\ s are quite demanding. It is possible to use lower quality voxel cone
|
||||
tracing in exchange for more performance.
|
||||
|
||||
.. image:: img/giprobe_quality.png
|
||||
BIN
tutorials/3d/img/average.webp
Normal file
|
After Width: | Height: | Size: 258 B |
BIN
tutorials/3d/img/bad.webp
Normal file
|
After Width: | Height: | Size: 244 B |
|
Before Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 1.7 MiB |
|
Before Width: | Height: | Size: 5.2 KiB |
BIN
tutorials/3d/img/faking_global_illumination_comparison.webp
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
tutorials/3d/img/gi_lightmap_gi_direct_and_indirect.webp
Normal file
|
After Width: | Height: | Size: 348 KiB |
BIN
tutorials/3d/img/gi_lightmap_gi_indirect_only.webp
Normal file
|
After Width: | Height: | Size: 348 KiB |
|
After Width: | Height: | Size: 358 KiB |
BIN
tutorials/3d/img/gi_none.webp
Normal file
|
After Width: | Height: | Size: 178 KiB |
BIN
tutorials/3d/img/gi_none_reflection_probe.webp
Normal file
|
After Width: | Height: | Size: 194 KiB |
BIN
tutorials/3d/img/gi_sdfgi.webp
Normal file
|
After Width: | Height: | Size: 412 KiB |
BIN
tutorials/3d/img/gi_ssil_only.webp
Normal file
|
After Width: | Height: | Size: 314 KiB |
BIN
tutorials/3d/img/gi_voxel_gi.webp
Normal file
|
After Width: | Height: | Size: 375 KiB |
BIN
tutorials/3d/img/global_illumination_example.webp
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
tutorials/3d/img/good.webp
Normal file
|
After Width: | Height: | Size: 246 B |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 151 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 587 KiB After Width: | Height: | Size: 587 KiB |
BIN
tutorials/3d/img/lightmap_gi_import.webp
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
BIN
tutorials/3d/img/lightmap_gi_mesh_import_meshes.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
BIN
tutorials/3d/img/reflection_probes_reflection_probe.webp
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
tutorials/3d/img/reflection_probes_reflection_probe_ssr.webp
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
tutorials/3d/img/reflection_probes_ssr.webp
Normal file
|
After Width: | Height: | Size: 46 KiB |
@@ -11,9 +11,6 @@
|
||||
standard_material_3d
|
||||
lights_and_shadows
|
||||
physical_light_and_camera_units
|
||||
reflection_probes
|
||||
gi_probes
|
||||
baked_lightmaps
|
||||
environment_and_post_processing
|
||||
3d_antialiasing
|
||||
resolution_scaling
|
||||
@@ -27,3 +24,17 @@
|
||||
mesh_lod
|
||||
visibility_ranges
|
||||
occlusion_culling
|
||||
|
||||
Global illumination
|
||||
-------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:name: toc-learn-features-3d-global-illumination
|
||||
|
||||
introduction_to_global_illumination
|
||||
using_voxel_gi
|
||||
sdfgi
|
||||
using_lightmap_gi
|
||||
reflection_probes
|
||||
faking_global_illumination
|
||||
|
||||
390
tutorials/3d/introduction_to_global_illumination.rst
Normal file
@@ -0,0 +1,390 @@
|
||||
.. _doc_introduction_to_global_illumination:
|
||||
|
||||
Introduction to global illumination
|
||||
===================================
|
||||
|
||||
What is global illumination?
|
||||
----------------------------
|
||||
|
||||
*Global illumination* is a catch-all term used to describe a system of lighting
|
||||
that uses both direct light (light that comes directly from a light source) and
|
||||
indirect light (light that bounces from a surface). In a 3D rendering engine,
|
||||
global illumination is one of the most important elements to achieving
|
||||
realistic lighting. Global illumination aims to mimic how light behaves
|
||||
in real life, such as light bouncing on surfaces and light being emitted
|
||||
from emissive materials.
|
||||
|
||||
In the example below, the entire scene is illuminated by an emissive material
|
||||
(the white square at the top). The white wall and ceiling on the back is tinted
|
||||
red and green close to the walls, as the light bouncing on the colored walls is
|
||||
being reflected back onto the rest of the scene.
|
||||
|
||||
.. image:: img/global_illumination_example.webp
|
||||
|
||||
Global illumination is composed of several key concepts:
|
||||
|
||||
Indirect diffuse lighting
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This is the lighting that does not change depending on the camera's angle.
|
||||
There are two main sources of indirect diffuse lighting:
|
||||
|
||||
- Light *bouncing* on surfaces. This bounced lighting is multiplied with the
|
||||
material's albedo color. The bounced lighting can then be reflected by other
|
||||
surfaces, with decreasing impact due to light attenuation. In real life,
|
||||
light bounces an infinite number of times. However, for performance
|
||||
reasons, this can't be simulated in a game engine. Instead, the number of
|
||||
bounces is typically limited to 1 or 2 (or up to 16 when baking lightmaps). A
|
||||
greater number of bounces will lead to more realistic light falloff in shaded
|
||||
areas, at the cost of lower performance or greater bake times.
|
||||
- Emissive materials can also emit light that can be bounced on surfaces.
|
||||
This acts as a form of *area lighting*. Instead of having an infinitely
|
||||
small point emit light using an OmniLight3D or SpotLight3D node,
|
||||
an area of a determined size will emit light using its own surface.
|
||||
|
||||
Direct diffuse lighting is already handled by the light nodes themselves, which
|
||||
means that global illumination algorithms only try to represent indirect
|
||||
lighting.
|
||||
|
||||
Different global illumination techniques offer varying levels of accuracy
|
||||
to represent indirect diffuse lighting. See the comparison table at the bottom
|
||||
of this page for more information.
|
||||
|
||||
To provide more accurate ambient occlusion for small objects, screen-space ambient occlusion
|
||||
(SSAO) can be enabled in the :ref:`environment <doc_environment_and_post_processing>`
|
||||
settings. SSAO has a significant performance cost, so make sure to disable
|
||||
it when targeting low-end hardware.
|
||||
|
||||
.. note::
|
||||
|
||||
Indirect diffuse lighting may be a source of color banding in scenes with no
|
||||
detailed textures. This results in light gradients not being smooth, but
|
||||
having a visible "stepping" effect instead. See the
|
||||
:ref:`doc_3d_rendering_limitations_color_banding` section in the 3D rendering
|
||||
limitations documentation for ways to reduce this effect.
|
||||
|
||||
Specular lighting
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Specular lighting is also referred to as *reflections*.
|
||||
This is the lighting that changes in intensity depending on the camera's angle.
|
||||
This specular lighting can be *direct* or *indirect*.
|
||||
|
||||
Most global illumination techniques offer a way to render specular lighting.
|
||||
However, the degree of accuracy at which specular lighting is rendered varies
|
||||
greatly from technique to technique. See the comparison table at the bottom
|
||||
of this page for more information.
|
||||
|
||||
To provide more accurate reflections for small objects, screen-space reflections (SSR)
|
||||
can be enabled in the :ref:`environment <doc_environment_and_post_processing>` settings.
|
||||
SSR has a significant performance cost (even more so than SSAO), so make sure to disable
|
||||
it when targeting low-end hardware.
|
||||
|
||||
.. _doc_introduction_to_global_illumination_comparison:
|
||||
|
||||
Which global illumination technique should I use?
|
||||
-------------------------------------------------
|
||||
|
||||
When determining a global illumination (GI) technique to use,
|
||||
there are several criteria to keep in mind:
|
||||
|
||||
- **Performance.** Real-time GI techniques are usually more expensive
|
||||
compared to semi-real-time or baked techniques. Note that most of the cost in
|
||||
GI rendering is spent on the GPU, rather than the CPU.
|
||||
- **Visuals.** On top of not performing the best, real-time GI techniques
|
||||
generally don't provide the best visual output. This is especially the case in
|
||||
a mostly static scene where the dynamic nature of real-time GI is not easily
|
||||
noticeable. If maximizing visual quality is your goal, baked techniques will
|
||||
often look better and will result in fewer light leaks.
|
||||
- **Real-time ability.** Some GI techniques are fully real-time,
|
||||
whereas others are only semi-real-time or aren't real-time at all.
|
||||
Semi-real-time techniques have restrictions that fully real-time techniques don't.
|
||||
For instance, dynamic objects may not contribute emissive lighting to the scene.
|
||||
Non-real-time techniques do not support *any* form of dynamic GI,
|
||||
so it must be faked using other techniques if needed (such as placing positional lights
|
||||
near emissive surfaces).
|
||||
Real-time ability also affects the GI technique's viability in procedurally
|
||||
generated levels.
|
||||
- **User work needed.** Some GI techniques are fully automatic, whereas others
|
||||
require careful planning and manual work on the user's side. Depending on your
|
||||
time budget, some GI techniques may be preferable to others.
|
||||
|
||||
Here's a comparison of all the global illumination techniques available in Godot:
|
||||
|
||||
Performance
|
||||
^^^^^^^^^^^
|
||||
|
||||
In order of performance from fastest to slowest:
|
||||
|
||||
- **ReflectionProbe:**
|
||||
|
||||
- ReflectionProbes with their update mode set to **Always** are much more
|
||||
expensive than probes with their update mode set to **Once** (the default).
|
||||
Suited for integrated graphics when using the **Once** update mode.
|
||||
*Available when using the Forward Mobile backend. Will be available in the Compatibility backend in later releases.*
|
||||
|
||||
- **LightmapGI:**
|
||||
|
||||
- Lights can be baked with indirect lighting only, or fully baked on a
|
||||
per-light basis to further improve performance. Hybrid setups can be used
|
||||
(such as having a real-time directional light and fully baked positional lights).
|
||||
Directional information can be enabled before baking to improve visuals at
|
||||
a small performance cost (and at the cost of larger file sizes).
|
||||
Suited for integrated graphics.
|
||||
*Available when using the Forward Mobile backend. Will be available in the Compatibility backend in later releases.*
|
||||
|
||||
- **VoxelGI:**
|
||||
|
||||
- The bake's number of subdivisions can be adjusted to balance between performance and quality.
|
||||
The VoxelGI rendering quality can be adjusted in the Project Settings.
|
||||
The rendering can optionally be performed at half resolution
|
||||
(and then linearly scaled) to improve performance significantly.
|
||||
**Not available** *when using the Forward Mobile or Compatibility backends.*
|
||||
|
||||
- **Screen-space indirect lighting (SSIL):**
|
||||
|
||||
- The SSIL quality and number of blur passes can be adjusted in the Project Settings.
|
||||
By default, SSIL rendering is performed at half resolution (and then linearly scaled)
|
||||
to ensure a reasonable performance level.
|
||||
**Not available** *when using the Forward Mobile or Compatibility backends.*
|
||||
|
||||
- **SDFGI:**
|
||||
|
||||
- The number of cascades can be adjusted to balance performance and quality.
|
||||
The number of rays thrown per frame can be adjusted in the Project Settings.
|
||||
The rendering can optionally be performed at half resolution
|
||||
(and then linearly scaled) to improve performance significantly.
|
||||
**Not available** *when using the Forward Mobile or Compatibility backends.*
|
||||
|
||||
Visuals
|
||||
^^^^^^^
|
||||
|
||||
For comparison, here's a 3D scene with no global illumination options used:
|
||||
|
||||
.. figure:: img/gi_none.webp
|
||||
:alt: A 3D scene without any form of global illumination (only constant environment lighting). The box and sphere near the camera are both dynamic objects.
|
||||
|
||||
A 3D scene without any form of global illumination (only constant environment lighting). The box and sphere near the camera are both dynamic objects.
|
||||
|
||||
Here's how Godot's various global illumination techniques compare:
|
||||
|
||||
- **VoxelGI:** |average| Good reflections and indirect lighting, but beware of leaks.
|
||||
|
||||
- Due to its voxel-based nature, VoxelGI will exhibit light leaks if walls and floors are too thin.
|
||||
It's recommended to make sure all solid surfaces are at least as thick as one voxel.
|
||||
|
||||
Streaking artifacts may also be visible on sloped surfaces. In this case,
|
||||
tweaking the bias properties or rotating the VoxelGI node can help combat
|
||||
this.
|
||||
|
||||
.. figure:: img/gi_voxel_gi.webp
|
||||
:alt: VoxelGI in action.
|
||||
|
||||
VoxelGI in action.
|
||||
|
||||
- **SDFGI:** |average| Good reflections and indirect lighting, but beware of leaks and visible cascade shifts.
|
||||
|
||||
- GI level of detail varies depending on the distance
|
||||
between the camera and surface.
|
||||
|
||||
Leaks can be reduced significantly by enabling the **Use Occlusion**
|
||||
property. This has a small performance cost, but it often results in fewer
|
||||
leaks compared to VoxelGI.
|
||||
|
||||
Cascade shifts may be visible when the camera moves fast. This can be made
|
||||
less noticeable by adjusting the cascade sizes or using fog.
|
||||
|
||||
.. figure:: img/gi_sdfgi.webp
|
||||
:alt: SDFGI in action.
|
||||
|
||||
SDFGI in action.
|
||||
|
||||
- **Screen-space indirect lighting (SSIL):** |average| Good *secondary* source of indirect lighting, but no reflections.
|
||||
|
||||
- SSIL is designed to be used as a complement to another GI technique such as
|
||||
VoxelGI, SDFGI or LightmapGI. SSIL works best for small-scale details, as it
|
||||
cannot provide accurate indirect lighting for large structures on its own.
|
||||
SSIL can provide real-time indirect lighting in situations where other GI
|
||||
techniques fail to capture small-scale details or dynamic objects. Its
|
||||
screen-space nature will result in some artifacts, especially when objects
|
||||
enter and leave the screen. SSIL works using the last frame's color (before
|
||||
post-processing) which means that emissive decals and custom shaders are
|
||||
included (as long as they're present on screen).
|
||||
|
||||
.. figure:: img/gi_ssil_only.webp
|
||||
:alt: SSIL in action (without any other GI technique). Notice the emissive lighting around the yellow box.
|
||||
|
||||
SSIL in action (without any other GI technique). Notice the emissive lighting around the yellow box.
|
||||
|
||||
- **LightmapGI:** |good| Excellent indirect lighting, decent reflections (optional).
|
||||
|
||||
- This is the only technique where the number of light bounces
|
||||
can be pushed above 2 (up to 16). When directional information
|
||||
is enabled, spherical harmonics (SH) are used
|
||||
to provide blurry reflections.
|
||||
|
||||
.. figure:: img/gi_lightmap_gi_indirect_only.webp
|
||||
:alt: LightmapGI in action. Only indirect lighting is baked here, but direct light can also be baked.
|
||||
|
||||
LightmapGI in action. Only indirect lighting is baked here, but direct light can also be baked.
|
||||
|
||||
- **ReflectionProbe:** |average| Good reflections, but poor indirect lighting.
|
||||
|
||||
- Indirect lighting can be disabled, set to a constant color spread throughout
|
||||
the probe, or automatically read from the probe's environment (and applied
|
||||
as a cubemap). This essentially acts as local ambient lighting. Reflections
|
||||
and indirect lighting are blended with other nearby probes.
|
||||
|
||||
.. figure:: img/gi_none_reflection_probe.webp
|
||||
:alt: ReflectionProbe in action (without any other GI technique). Notice the reflective sphere.
|
||||
|
||||
ReflectionProbe in action (without any other GI technique). Notice the reflective sphere.
|
||||
|
||||
Real-time ability
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
- **VoxelGI:** |good| Fully real-time.
|
||||
|
||||
- Indirect lighting and reflections are fully real-time. Dynamic objects can
|
||||
receive GI *and* contribute to it with their emissive surfaces. Custom
|
||||
shaders can also emit their own light, which will be emitted accurately.
|
||||
|
||||
Viable for procedurally generated levels *if they are generated in advance*
|
||||
(and not during gameplay). Baking requires several seconds or more to complete,
|
||||
but it can be done from both the editor and an exported project.
|
||||
|
||||
- **SDFGI:** |average| Semi-real-time.
|
||||
|
||||
- Cascades are generated in real-time, making SDFGI
|
||||
viable for procedurally generated levels (including when structures are generated
|
||||
during gameplay).
|
||||
|
||||
Dynamic objects can *receive* GI, but not *contribute* to it. Emissive lighting
|
||||
will only update when an object enters a cascade, so it may still work for
|
||||
slow-moving objects.
|
||||
|
||||
- **Screen-space indirect lighting (SSIL):** |good| Fully real-time.
|
||||
|
||||
- SSIL works with both static and dynamic lights. It also works with both
|
||||
static and dynamic occluders (including emissive materials).
|
||||
|
||||
- **LightmapGI:** |bad| Baked, and therefore not real-time.
|
||||
|
||||
- Both indirect lighting and SH reflections are baked and can't be changed at
|
||||
run-time. Real-time GI must be
|
||||
:ref:`simulated via other means <doc_faking_global_illumination>`,
|
||||
such as real-time positional lights. Dynamic objects receive indirect lighting
|
||||
via light probes, which can be placed automatically or manually by the user
|
||||
(LightmapProbe node). Not viable for procedurally generated levels,
|
||||
as baking lightmaps is only possible from the editor.
|
||||
|
||||
- **ReflectionProbe:** |average| Optionally real-time.
|
||||
|
||||
- By default, reflections update when the probe is moved.
|
||||
They update as often as possible if the update mode
|
||||
is set to **Always** (which is expensive).
|
||||
|
||||
- Indirect lighting must be configured manually by the user, but can be changed
|
||||
at run-time without causing an expensive computation to happen behind the scenes.
|
||||
This makes ReflectionProbes viable for procedurally generated levels.
|
||||
|
||||
User work needed
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
- **VoxelGI:** One or more VoxelGI nodes need to be created and baked.
|
||||
|
||||
- Adjusting extents correctly is required to get good results. Additionally
|
||||
rotating the node and baking again can help combat leaks or streaking
|
||||
artifacts in certain situations. Bake times are fast – usually below
|
||||
10 seconds for a scene of medium complexity.
|
||||
|
||||
- **SDFGI:** Very little.
|
||||
|
||||
- SDFGI is fully automatic; it only needs to be enabled in the Environment resource.
|
||||
The only manual work required is to set MeshInstances' bake mode property correctly.
|
||||
No node needs to be created, and no baking is required.
|
||||
|
||||
- **Screen-space indirect lighting (SSIL):** Very little.
|
||||
|
||||
- SSIL is fully automatic; it only needs to be enabled in the Environment resource.
|
||||
No node needs to be created, and no baking is required.
|
||||
|
||||
- **LightmapGI:** Requires UV2 setup and baking.
|
||||
|
||||
- Static meshes must be reimported with UV2 and lightmap generation enabled.
|
||||
On a dedicated GPU, bake times are relatively fast thanks to the GPU-based
|
||||
lightmap baking – usually below 1 minute for a scene of medium complexity.
|
||||
|
||||
- **ReflectionProbe:** Placed manually by the user.
|
||||
|
||||
.. |good| image:: img/good.webp
|
||||
|
||||
.. |average| image:: img/average.webp
|
||||
|
||||
.. |bad| image:: img/bad.webp
|
||||
|
||||
Summary
|
||||
^^^^^^^
|
||||
|
||||
If you are unsure about which GI technique to use:
|
||||
|
||||
- For desktop games, it's a good idea to start with :ref:`SDFGI <doc_sdfgi>`
|
||||
first as it requires the least amount of setup. Move to other GI techniques
|
||||
later if needed. To improve performance on low-end GPUs and integrated
|
||||
graphics, consider adding an option to disable SDFGI or :ref:`VoxelGI
|
||||
<doc_using_voxel_gi>` in your game's settings. SDFGI can be disabled in the
|
||||
Environment resource, and VoxelGI can be disabled by hiding the VoxelGI
|
||||
node(s). To further improve visuals on high-end setups, add an option to
|
||||
enable SSIL in your game's settings.
|
||||
- For mobile games, :ref:`LightmapGI <doc_using_lightmap_gi>` and
|
||||
:ref:`ReflectionProbes <doc_reflection_probes>` are the only supported options.
|
||||
See also :ref:`doc_introduction_to_global_illumination_alternatives`.
|
||||
|
||||
.. _doc_introduction_to_global_illumination_gi_mode_recommendations:
|
||||
|
||||
Which global illumination mode should I use on meshes and lights?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Regardless of which global illumination technique you use, there is no
|
||||
universally "better" global illumination mode. Still, here are some
|
||||
recommendations for meshes:
|
||||
|
||||
- For static level geometry, use the **Static** global illumination mode *(default)*.
|
||||
- For small dynamic geometry and players/enemies, use the **Disabled** global
|
||||
illumination mode. Small dynamic geometry will not be able to contribute a significant
|
||||
amount of indirect lighting, due to the geometry being smaller than a voxel.
|
||||
If you need indirect lighting for small dynamic objects, it can be simulated
|
||||
using an OmniLight3D or SpotLight3D node parented to the object.
|
||||
- For *large* dynamic level geometry (such as a moving train), use the
|
||||
**Dynamic** global illumination mode. Note that this only has an effect with
|
||||
VoxelGI, as SDFGI and LightmapGI do not support global illumination with
|
||||
dynamic objects.
|
||||
|
||||
Here are some recommendations for light bake modes:
|
||||
|
||||
- For static level lighting, use the **Static** bake mode.
|
||||
The **Static** mode is also suitable for dynamic lights that don't change
|
||||
much during gameplay, such as a flickering torch.
|
||||
- For short-lived dynamic effects (such as a weapon), use the **Disabled**
|
||||
bake mode to improve performance.
|
||||
- For long-lived dynamic effects (such as a rotating alarm light), use the
|
||||
**Dynamic** bake mode to improve quality *(default)*. Note that this only has
|
||||
an effect with VoxelGI and SDFGI, as LightmapGI does not support global
|
||||
illumination with dynamic lights.
|
||||
|
||||
.. _doc_introduction_to_global_illumination_alternatives:
|
||||
|
||||
Alternatives to GI techniques
|
||||
-----------------------------
|
||||
|
||||
If none of the GI techniques mentioned above fits, it's still possible to
|
||||
:ref:`simulate GI by placing additional lights manually <doc_faking_global_illumination>`.
|
||||
This requires more manual work, but it can offer good performance *and* good
|
||||
visuals if done right. This approach is still used in many modern games to this
|
||||
day.
|
||||
|
||||
When targeting low-end hardware in situations where using LightmapGI is not
|
||||
viable (such as procedurally generated levels), relying on environment lighting
|
||||
alone or a constant ambient light factor may be a necessity. This may result in
|
||||
flatter visuals, but adjusting the ambient light color and sky contribution
|
||||
still makes it possible to achieve acceptable results in most cases.
|
||||
@@ -14,7 +14,7 @@ result. Light can come from several types of sources in a scene:
|
||||
- Light Nodes: Directional, Omni and Spot.
|
||||
- Ambient Light in the
|
||||
:ref:`Environment <class_Environment>`.
|
||||
- Baked Light (read :ref:`doc_baked_lightmaps`).
|
||||
- Baked Light (read :ref:`doc_using_lightmap_gi`).
|
||||
|
||||
The emission color is a material property. You can read more about it
|
||||
in the :ref:`doc_standard_material_3d` tutorial.
|
||||
@@ -35,7 +35,7 @@ Each one has a specific function:
|
||||
- **Indirect Energy**: Secondary multiplier used with indirect light (light bounces). This works in baked light or GIProbe.
|
||||
- **Negative**: Light becomes subtractive instead of additive. It's sometimes useful to manually compensate some dark corners.
|
||||
- **Specular**: Affects the intensity of the specular blob in objects affected by this light. At zero, this light becomes a pure diffuse light.
|
||||
- **Bake Mode**: Sets the bake mode for the light. For more information see :ref:`doc_baked_lightmaps`
|
||||
- **Bake Mode**: Sets the bake mode for the light. For more information see :ref:`doc_using_lightmap_gi`
|
||||
- **Cull Mask**: Objects that are in the selected layers below will be affected by this light.
|
||||
Note that objects disabled via this cull mask will still cast shadows.
|
||||
If you don't want disabled objects to cast shadows, adjust the ``cast_shadow`` property on the
|
||||
|
||||
@@ -3,108 +3,166 @@
|
||||
Reflection probes
|
||||
=================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
As stated in the :ref:`doc_standard_material_3d`, objects can show reflected and/or
|
||||
diffuse light. Reflection probes are used as a source of reflected *and* ambient
|
||||
light for objects inside their area of influence. They can be used to provide
|
||||
more accurate reflections than :ref:`VoxelGI <doc_using_voxel_gi>` and
|
||||
:ref:`SDFGI <doc_sdfgi>` while being fairly cheap on system resources.
|
||||
|
||||
As stated in the :ref:`doc_standard_material_3d`, objects can show reflected or diffuse light.
|
||||
Reflection probes are used as a source of reflected and ambient light for objects inside their area of influence.
|
||||
Since reflection probes can also store ambient light, they can be used as a
|
||||
low-end alternative to VoxelGI and SDFGI when :ref:`baked lightmaps
|
||||
<doc_using_lightmap_gi>` aren't viable (e.g. in procedurally generated levels).
|
||||
|
||||
A probe of this type captures the surroundings (as a sort of 360 degrees image), and stores versions
|
||||
of it with increasing levels of *blur*. This is used to simulate roughness in materials, as well as ambient lighting.
|
||||
Reflection probes can also be used at the same time as screen-space reflections
|
||||
to provide reflections for off-screen objects. In this case, Godot will blend
|
||||
together the screen-space reflections and reflections from reflection probes.
|
||||
|
||||
While these probes are an efficient way of storing reflections, they have a few shortcomings:
|
||||
.. seealso::
|
||||
|
||||
* They are efficient to render, but expensive to compute. This leads to a default behavior where they only capture on scene load.
|
||||
* They work best for rectangular shaped rooms or places, otherwise the reflections shown are not as faithful (especially when roughness is 0).
|
||||
Not sure if ReflectionProbe is suited to your needs?
|
||||
See :ref:`doc_introduction_to_global_illumination_comparison`
|
||||
for a comparison of GI techniques available in Godot 4.
|
||||
|
||||
Setting up
|
||||
----------
|
||||
Visual comparison
|
||||
-----------------
|
||||
|
||||
Create a ReflectionProbe node and wrap it around the area where you want to have reflections:
|
||||
.. figure:: img/gi_none.webp
|
||||
:align: center
|
||||
:alt: Reflection probe disabled. Environment sky is used as a fallback.
|
||||
|
||||
.. image:: img/refprobe_setup.png
|
||||
Reflection probe disabled. Environment sky is used as a fallback.
|
||||
|
||||
This should result in immediate local reflections. If you are using a Sky texture,
|
||||
reflections are by default blended with it.
|
||||
.. figure:: img/gi_none_reflection_probe.webp
|
||||
:align: center
|
||||
:alt: Reflection probe enabled.
|
||||
|
||||
By default, on interiors, reflections may appear not to have much consistence.
|
||||
In this scenario, make sure to tick the *"Box Correct"* property.
|
||||
Reflection probe enabled.
|
||||
|
||||
.. image:: img/refprobe_box_property.png
|
||||
By combining reflection probes with screen-space reflections, you can get the
|
||||
best of both worlds: high-quality reflections for general room structure (that
|
||||
remain present when off-screen), while also having real-time reflections for
|
||||
small details.
|
||||
|
||||
.. figure:: img/reflection_probes_reflection_probe.webp
|
||||
:align: center
|
||||
:alt: Reflections in a room using ReflectionProbe only.
|
||||
|
||||
This setting changes the reflection from an infinite skybox to reflecting
|
||||
a box the size of the probe:
|
||||
Reflections in a room using ReflectionProbe only. Notice how small details
|
||||
don't have any reflections.
|
||||
|
||||
.. image:: img/refprobe_boxcorrect.png
|
||||
.. figure:: img/reflection_probes_ssr.webp
|
||||
:align: center
|
||||
:alt: Reflections in a room using screen-space reflections only.
|
||||
|
||||
Adjusting the box walls may help improve the reflection a bit, but it will
|
||||
always look best in box shaped rooms.
|
||||
Reflections in a room using screen-space reflections only. Notice how the
|
||||
reflection on the sides of the room's walls is partly missing due to being
|
||||
off-screen.
|
||||
|
||||
The probe captures the surrounding from the center of the gizmo. If, for some
|
||||
reason, the room shape or contents occlude the center, it
|
||||
can be displaced to an empty place by moving the handles in the center:
|
||||
.. figure:: img/reflection_probes_reflection_probe_ssr.webp
|
||||
:align: center
|
||||
:alt: Reflections in a room using ReflectionProbe and screen-space reflections together.
|
||||
|
||||
.. image:: img/refprobe_center_gizmo.png
|
||||
Reflections in a room using ReflectionProbe and screen-space reflections together.
|
||||
The screen-space reflections are blended with the reflection probe,
|
||||
acting as a fallback in situations where the reflection probe fails to display
|
||||
any reflection.
|
||||
|
||||
By default, shadow mapping is disabled when rendering probes (only in the
|
||||
rendered image inside the probe, not the actual scene). This is
|
||||
a way to save on performance and memory. If you want shadows in the probe,
|
||||
they can be toggled on/off with the *Enable Shadow* setting:
|
||||
Setting up a ReflectionProbe
|
||||
----------------------------
|
||||
|
||||
.. image:: img/refprobe_shadows.png
|
||||
- Add a :ref:`class_ReflectionProbe` node.
|
||||
- Configure the ReflectionProbe's extents in the inspector to fit your scene. To
|
||||
get reasonably accurate reflections, you should generally have one
|
||||
ReflectionProbe node per room (sometimes more for large rooms).
|
||||
|
||||
Finally, keep in mind that you may not want the Reflection Probe to render some
|
||||
objects. A typical scenario is an enemy inside the room which will
|
||||
move around. To keep objects from being rendered in the reflections,
|
||||
use the *Cull Mask* setting:
|
||||
.. tip::
|
||||
|
||||
.. image:: img/refprobe_cullmask.png
|
||||
Remember that ReflectionProbe extents don't have to be square, and you can
|
||||
even rotate the ReflectionProbe node to fit rooms that aren't aligned with
|
||||
the X/Z grid. Use this to your advantage to better cover rooms without
|
||||
having to place too many ReflectionProbe nodes.
|
||||
|
||||
Interior vs exterior
|
||||
--------------------
|
||||
ReflectionProbe properties
|
||||
--------------------------
|
||||
|
||||
If you are using reflection probes in an interior setting, it is recommended
|
||||
that the **Interior** property be enabled. This stops
|
||||
the probe from rendering the sky and also allows custom ambient lighting settings.
|
||||
- **Update Mode:** Controls when the reflection probe updates.
|
||||
**Once** only renders the scene once every time the ReflectionProbe is moved.
|
||||
This makes it much faster to render compared to the **Always** update mode,
|
||||
which forces the probe to re-render everything around it every frame.
|
||||
Leave this property on **Once** (default) unless you need the reflection probe
|
||||
to update every frame.
|
||||
- **Intensity:** The brightness of the reflections and ambient lighting. This
|
||||
usually doesn't need to be changed from its default value of ``1.0``, but you
|
||||
can decrease it ``1.0`` if you find that reflections look too strong.
|
||||
- **Max Distance:** Controls the maximum distance used by the ReflectionProbe's
|
||||
internal camera. The distance is always at least equal to the **Extents**, but
|
||||
this can be increased to make objects located outside the extents visible in
|
||||
reflections. *This property does not affect the maximum distance at which the
|
||||
ReflectionProbe itself is visible.*
|
||||
- **Extents:** The area that will be affected by the ReflectionProbe's lighting
|
||||
and reflections.
|
||||
- **Origin Offset:** The origin to use for the internal camera used for
|
||||
reflection probe rendering. This must always be constrained within the
|
||||
**Extents**. If needed, adjust this to prevent the reflection from being
|
||||
obstructed by a solid object located exactly at the center of the
|
||||
ReflectionProbe.
|
||||
- **Box Projection:** Controls whether parallax correction should be used when
|
||||
rendering the reflection probe. This adjusts the reflection's appearance
|
||||
depending on the camera's position (relative to the reflection probe). This
|
||||
has a small performance cost, but the quality increase is often worth it in
|
||||
box-shaped rooms. Note that this effect doesn't work quite as well in rooms
|
||||
with less regular shapes (such as ellipse-shaped rooms).
|
||||
- **Interior:** If enabled, ambient lighting will not be sourced from the
|
||||
environment sky, and the background sky won't be rendered onto the reflection
|
||||
probe.
|
||||
- **Enable Shadows:** Controls whether real-time light shadows should be
|
||||
rendered within the reflection probe. Enable this to improve reflection
|
||||
quality at the cost of performance. This should be left disabled for
|
||||
reflection probes with the **Always** mode, as it's very expensive to render
|
||||
reflections with shadows every frame. Fully :ref:`baked light <doc_using_lightmap_gi>`
|
||||
shadows are not affected by this setting and will be rendered in the
|
||||
reflection probe regardless.
|
||||
- **Cull Mask:** Controls which objects are visible in the reflection. This can
|
||||
be used to improve performance by excluding small objects from the reflection.
|
||||
This can also be used to prevent an object from having self-reflection
|
||||
artifacts in situations where **Origin Offset** can't be used.
|
||||
- **Mesh LOD Threshold:** The automatic level of detail threshold to use for
|
||||
rendering meshes within the reflection. This only affects meshes that have
|
||||
automatic LODs generated for them. Higher values can improve performance by
|
||||
using less detailed geometry, especially for objects that are far away from
|
||||
the reflection's origin. The visual difference of using less detailed objects
|
||||
is usually not very noticeable during gameplay, especially in rough
|
||||
reflections.
|
||||
|
||||
.. image:: img/refprobe_ambient.png
|
||||
The Ambient category features several properties to adjust ambient lighting
|
||||
rendered by the ReflectionProbe:
|
||||
|
||||
When probes are set to **Interior**, custom constant ambient lighting can be
|
||||
specified per probe. Just choose a color and an energy.
|
||||
- **Mode:** If set to **Disabled**, no ambient light is added by the probe. If
|
||||
set to **Environment**, the ambient light color is automatically sampled from
|
||||
the environment sky (if **Interior** is disabled) and the reflection's average
|
||||
color. If set to **Constant Color**, the color specified in the **Color**
|
||||
property is used instead. The **Constant Color** mode can be used as an
|
||||
approximation of area lighting.
|
||||
- **Color:** The color to use when the ambient light mode is set to **Constant Mode**.
|
||||
- **Color Energy:** The multiplier to use for the ambient light custom
|
||||
**Color**. This only has an effect when the ambient light mode is **Custom
|
||||
Color**.
|
||||
|
||||
Optionally, you can blend this ambient light with the probe diffuse capture by
|
||||
tweaking the **Ambient Contribution** property (0.0 means pure ambient color,
|
||||
while 1.0 means pure diffuse capture).
|
||||
ReflectionProbe blending
|
||||
------------------------
|
||||
|
||||
Blending
|
||||
--------
|
||||
To make transitions between reflection sources smoother, Godot supports automatic
|
||||
probe blending:
|
||||
|
||||
Multiple reflection probes can be used, and Godot will blend them where they overlap using a smart algorithm:
|
||||
- Up to 4 ReflectionProbes can be blended together at a given location.
|
||||
A ReflectionProbe will also fade out smoothly back to environment lighting
|
||||
when it isn't touching any other ReflectionProbe node.
|
||||
- SDFGI and VoxelGI will blend in smoothly with ReflectionProbes if used.
|
||||
This allows placing ReflectionProbes strategically to get more accurate (or fully real-time)
|
||||
reflections where needed, while still having rough reflections available in the
|
||||
VoxelGI or SDFGI's area of influence.
|
||||
|
||||
.. image:: img/refprobe_blending.png
|
||||
|
||||
As you can see, this blending is never perfect (after all, these are
|
||||
box reflections, not real reflections), but these artifacts
|
||||
are only visible when using perfectly mirrored reflections.
|
||||
Normally, scenes have normal mapping and varying levels of roughness, which
|
||||
can hide this.
|
||||
|
||||
Alternatively, Reflection Probes work well blended together with Screen Space
|
||||
Reflections to solve these problems. Combining them makes local reflections appear
|
||||
more faithful, while probes are only used as a fallback when no screen-space information is found:
|
||||
|
||||
.. image:: img/refprobe_ssr.png
|
||||
|
||||
Finally, blending interior and exterior probes is the recommended approach when making
|
||||
levels that combine both interiors and exteriors. Near the door, a probe can
|
||||
be marked as *exterior* (so it will get sky reflections) while on the inside, it can be interior.
|
||||
|
||||
Reflection atlas
|
||||
----------------
|
||||
|
||||
In the current renderer implementation, all probes are the same size and
|
||||
are fit into a Reflection Atlas. The size and amount of probes can be
|
||||
customized in Project Settings -> Quality -> Reflections
|
||||
|
||||
.. image:: img/refprobe_atlas.png
|
||||
To make several ReflectionProbes blend with each other, you need to have part of
|
||||
each ReflectionProbe overlap each other's area. The extents should only overlap
|
||||
as little possible with other reflection probes to improve rendering performance
|
||||
(typically a few units in 3D space).
|
||||
|
||||
229
tutorials/3d/sdfgi.rst
Normal file
@@ -0,0 +1,229 @@
|
||||
.. _doc_sdfgi:
|
||||
|
||||
Signed distance field global illumination (SDFGI)
|
||||
=================================================
|
||||
|
||||
Signed distance field global illumination (SDFGI) is a novel technique available
|
||||
in Godot 4.0. It provides semi-real-time global illumination that scales to any
|
||||
world size and works with procedurally generated levels.
|
||||
|
||||
SDFGI supports dynamic lights, but *not* dynamic occluders or dynamic emissive surfaces.
|
||||
Therefore, SDFGI provides better real-time ability than
|
||||
:ref:`baked lightmaps <doc_using_lightmap_gi>`, but worse real-time ability than
|
||||
:ref:`VoxelGI <doc_using_voxel_gi>`.
|
||||
|
||||
From a performance standpoint, SDFGI is one of the most demanding global illumination
|
||||
techniques in Godot. Like with VoxelGI, there are still many settings available to tweak
|
||||
its performance requirements at the cost of quality.
|
||||
|
||||
.. important::
|
||||
|
||||
SDFGI is only supported when using the Forward Plus rendering backend,
|
||||
not the Forward Mobile or Compatibility backends.
|
||||
|
||||
.. seealso::
|
||||
|
||||
Not sure if SDFGI is suited to your needs?
|
||||
See :ref:`doc_introduction_to_global_illumination_comparison`
|
||||
for a comparison of GI techniques available in Godot 4.
|
||||
|
||||
Visual comparison
|
||||
-----------------
|
||||
|
||||
.. figure:: img/gi_none.webp
|
||||
:alt: SDFGI disabled.
|
||||
|
||||
SDFGI disabled.
|
||||
|
||||
.. figure:: img/gi_sdfgi.webp
|
||||
:alt: SDFGI enabled.
|
||||
|
||||
SDFGI enabled.
|
||||
|
||||
Setting up SDFGI
|
||||
----------------
|
||||
|
||||
In Godot, SDFGI is the global illumination technique with the fewest required
|
||||
steps to enable:
|
||||
|
||||
1. Make sure your MeshInstance nodes have their **Global Illumination > Mode**
|
||||
property set to **Static** in the inspector.
|
||||
|
||||
- For imported 3D scenes, the bake mode can be configured in the Import dock
|
||||
after selecting the 3D scene file in the FileSystem dock.
|
||||
|
||||
2. Add a WorldEnvironment node and create an Environment resource for it.
|
||||
3. Edit the Environment resource, scroll down to the **SDFGI** section and unfold it.
|
||||
4. Enable **SDFGI > Enabled**. SDFGI will automatically follow the camera when it
|
||||
moves, so you do not need to configure extents (unlike VoxelGI).
|
||||
|
||||
Environment SDFGI properties
|
||||
----------------------------
|
||||
|
||||
In the Environment resource, there are several properties available to adjust
|
||||
SDFGI appearance and quality:
|
||||
|
||||
- **Use Occlusion:** If enabled, SDFGI will throw additional rays to find and
|
||||
reduce light leaks. This has a performance cost, so only enable this property
|
||||
if you actually need it.
|
||||
- **Read Sky Light:** If enabled, the environment lighting is represented in the
|
||||
global illumination. This should be enabled in outdoor scenes and disabled in
|
||||
fully indoor scenes.
|
||||
- **Bounce Feedback:** By default, indirect lighting only bounces once when
|
||||
using SDFGI. Setting this value above ``0.0`` will cause SDFGI to bounce more
|
||||
than once, which provides more realistic indirect lighting at a small
|
||||
performance cost. Sensible values are usually between ``0.3`` and ``1.0``
|
||||
depending on the scene. Note that in some scenes, values above ``0.5`` can
|
||||
cause infinite feedback loops to happen, causing the scene to become extremely
|
||||
bright in a few seconds' time.
|
||||
If your indirect lighting looks "splotchy", consider increasing this value above
|
||||
``0.0`` to get more uniform-looking lighting. If your lighting ends up looking
|
||||
too bright as a result, decrease **Energy** to compensate.
|
||||
- **Cascades:** Higher values result in more detailed GI information
|
||||
(and/or greater maximum distance), but are significantly more expensive on the
|
||||
CPU and GPU. The performance cost of having more cascades especially increases
|
||||
when the camera moves fast, so consider decreasing this to ``4`` or lower
|
||||
if your camera moves fast.
|
||||
- **Min Cell Size:** The minimum SDFGI cell size to use for the nearest, most detailed
|
||||
cascade. Lower values result in more accurate indirect lighting and reflection
|
||||
at the cost of lower performance.
|
||||
Adjusting this setting also affects **Cascade 0 Distance** and **Max Distance** automatically.
|
||||
- **Cascade 0 Distance:** The distance at which the nearest, most detailed
|
||||
cascade ends. Greater values make the nearest cascade transition less noticeable,
|
||||
at the cost of reducing the level of detail in the nearest cascade.
|
||||
Adjusting this setting also affects **Min Cell Size** and **Max Distance** automatically.
|
||||
- **Max Distance:** Controls how far away the signed distance field will be computed
|
||||
(for the least detailed cascade). SDFGI will not have any effect past this distance.
|
||||
This value should always be set below the Camera's Far value, as there is no benefit
|
||||
in computing SDFGI past the viewing distance.
|
||||
Adjusting this setting also affects **Min Cell Size** and **Cascade 0 Distance** automatically.
|
||||
- **Y Scale:** Controls how far apart SDFGI probes are spread *vertically*.
|
||||
By default, vertical spread is the same as horizontal. However, since most
|
||||
game scenes aren't highly vertical, setting the Y Scale to
|
||||
``75%`` or even ``50%`` can provide better quality and reduce light leaks
|
||||
without impacting performance.
|
||||
- **Energy:** The brightness multiplier for SDFGI's indirect lighting.
|
||||
- **Normal Bias:** The normal bias to use for SDFGI's probe ray bounces.
|
||||
Unlike **Probe Bias**, this only increases the value in relation to the
|
||||
mesh's normals. This makes the bias adjustment more nuanced and avoids
|
||||
increasing the bias too much for no reason. Increase this
|
||||
value if you notice striping artifacts in indirect lighting or reflections.
|
||||
- **Probe Bias:** The bias to use for SDFGI's probe ray bounces. Increase this
|
||||
value if you notice striping artifacts in indirect lighting or reflections.
|
||||
|
||||
SDFGI interaction with lights and objects
|
||||
-----------------------------------------
|
||||
|
||||
The amount of indirect energy emitted by a light is governed by its color,
|
||||
energy *and* indirect energy properties. To make a specific light emit more
|
||||
or less indirect energy without affecting the amount of direct light emitted
|
||||
by the light, adjust the **Indirect Energy** property in the Light3D inspector.
|
||||
|
||||
To ensure correct visuals when using SDFGI, you must configure your meshes
|
||||
and lights' global illumination properties according to their *purpose* in the
|
||||
scene (static or dynamic).
|
||||
|
||||
There are 3 global illumination modes available for meshes:
|
||||
|
||||
- **Disabled:** The mesh won't be taken into account in SDFGI generation.
|
||||
The mesh will receive indirect lighting from the scene, but it will not
|
||||
contribute indirect lighting to the scene.
|
||||
- **Static (default):** The mesh will be taken into account in SDFGI generation.
|
||||
The mesh will both receive *and* contribute indirect lighting to the scene. If
|
||||
the mesh is changed in any way after SDFGI is generated, the camera must move
|
||||
away from the object then move back close to it for SDFGI to regenerate.
|
||||
Alternatively, SDFGI can be toggled off and back on. If neither is done,
|
||||
indirect lighting will look incorrect.
|
||||
- **Dynamic (not supported with SDFGI):** The mesh won't be taken into account in SDFGI generation.
|
||||
The mesh will receive indirect lighting from the scene, but it will not
|
||||
contribute indirect lighting to the scene.
|
||||
*This acts identical to the **Disabled** bake mode when using SDFGI.*
|
||||
|
||||
Additionally, there are 3 bake modes available for lights
|
||||
(DirectionalLight3D, OmniLight3D and SpotLight3D):
|
||||
|
||||
- **Disabled:** The light won't be taken into account for SDFGI baking.
|
||||
The light won't contribute indirect lighting to the scene.
|
||||
- **Static:** The light will be taken into account for SDFGI baking. The light
|
||||
will contribute indirect lighting to the scene. If the light is changed in any
|
||||
way after baking, indirect lighting will look incorrect until the camera moves
|
||||
away from the light and back (which causes SDFGI to be baked again). will look
|
||||
incorrect. If in doubt, use this mode for level lighting.
|
||||
- **Dynamic (default):** The light won't be taken into account for SDFGI baking,
|
||||
but it will still contribute indirect lighting to the scene in real-time.
|
||||
This option is slower compared to **Static**. Only use the **Dynamic** global
|
||||
illumination mode on lights that will change significantly during gameplay.
|
||||
|
||||
.. note::
|
||||
|
||||
The amount of indirect energy emitted by a light depends on its color,
|
||||
energy *and* indirect energy properties. To make a specific light emit more
|
||||
or less indirect energy without affecting the amount of direct light emitted
|
||||
by the light, adjust the **Indirect Energy** property in the Light3D inspector.
|
||||
|
||||
.. seealso::
|
||||
|
||||
See :ref:`doc_introduction_to_global_illumination_gi_mode_recommendations`
|
||||
for general usage recommendations.
|
||||
|
||||
Adjusting SDFGI performance and quality
|
||||
---------------------------------------
|
||||
|
||||
Since SDFGI is relatively demanding, it will perform best on systems with recent
|
||||
dedicated GPUs. On older dedicated GPUs and integrated graphics,
|
||||
tweaking the settings is necessary to achieve reasonable performance.
|
||||
|
||||
In the Project Settings' **Rendering > Global Illumination** section,
|
||||
SDFGI quality can also be adjusted in several ways:
|
||||
|
||||
- **Sdfgi > Probe Ray Count:** Higher values result in better quality,
|
||||
at the cost of higher GPU usage. If this value is set too low,
|
||||
this can cause surfaces to have visible "splotches" of indirect lighting on
|
||||
them due to the number of rays thrown being very low.
|
||||
- **Sdfgi > Frames To Converge:** Higher values result in better quality, but GI will take
|
||||
more time to fully converge. The effect of this setting is especially noticeable when first
|
||||
loading a scene, or when lights with a bake mode other than **Disabled** are moving fast.
|
||||
If this value is set too low, this can cause surfaces to have visible "splotches"
|
||||
of indirect lighting on them due to the number of rays thrown being very low.
|
||||
If your scene's lighting doesn't have fast-moving lights that contribute to GI,
|
||||
consider setting this to ``30`` to improve quality without impacting performance.
|
||||
- **Sdfgi > Frames To Update Light:** Lower values result in moving lights being
|
||||
reflected faster, at the cost of higher GPU usage. If your scene's lighting
|
||||
doesn't have fast-moving lights that contribute to GI, consider setting this
|
||||
to ``16`` to improve performance.
|
||||
- **Gi > Use Half Resolution:** If enabled, both SDFGI and VoxelGI will have
|
||||
their GI buffer rendering at halved resolution. For instance, when rendering
|
||||
in 3840×2160, the GI buffer will be computed at a 1920×1080 resolution.
|
||||
Enabling this option saves a lot of GPU time, but it can introduce visible
|
||||
aliasing around thin details.
|
||||
|
||||
SDFGI rendering performance also depends on the number of cascades and
|
||||
the cell size chosen in the Environment resource (see above).
|
||||
|
||||
SDFGI caveats
|
||||
-------------
|
||||
|
||||
SDFGI has some downsides due to its cascaded nature. When the camera moves,
|
||||
cascade shifts may be visible in indirect lighting. This can be alleviated
|
||||
by adjusting the cascade size, but also by adding fog (which will make distant
|
||||
cascade shifts less noticeable).
|
||||
|
||||
Additionally, performance will suffer if the camera moves too fast.
|
||||
This can be fixed in two ways:
|
||||
|
||||
- Ensuring the camera doesn't move too fast in any given situation.
|
||||
- Temporarily disabling SDFGI in the Environment resource if the camera needs
|
||||
to be moved at a high speed, then enabling SDFGI once the camera speed slows down.
|
||||
|
||||
When SDFGI is enabled, it will also take some time for global illumination
|
||||
to be fully converged (25 frames by default). This can create a noticeable transition
|
||||
effect while GI is still converging. To hide this, you can use a ColorRect node
|
||||
that spans the whole viewport and fade it out when switching scenes using an
|
||||
AnimationPlayer node.
|
||||
|
||||
The signed distance field is only updated when the camera moves in and out of a
|
||||
cascade. This means that if geometry is modified in the distance, the global
|
||||
illumination appearance will be correct once the camera gets closer. However, if
|
||||
a nearby object with a bake mode set to **Static** or **Dynamic** is moved (such
|
||||
as a door), the global illumination will appear incorrect until the camera moves
|
||||
away from the object.
|
||||
@@ -267,9 +267,9 @@ Emission
|
||||
--------
|
||||
|
||||
*Emission* specifies how much light is emitted by the material (keep in mind this
|
||||
does not include light surrounding geometry unless :ref:`doc_gi_probes` are used).
|
||||
This value is added to the resulting final image and is not affected by other
|
||||
lighting in the scene.
|
||||
does not include light surrounding geometry unless :ref:`VoxelGI <doc_using_voxel_gi>`
|
||||
or :ref:`SDFGI <doc_sdfgi>` are used). This value is added to the resulting
|
||||
final image and is not affected by other lighting in the scene.
|
||||
|
||||
.. image:: img/spatial_material15.png
|
||||
|
||||
|
||||
377
tutorials/3d/using_lightmap_gi.rst
Normal file
@@ -0,0 +1,377 @@
|
||||
.. _doc_using_lightmap_gi:
|
||||
|
||||
Using Lightmap global illumination
|
||||
==================================
|
||||
|
||||
Baked lightmaps are a workflow for adding indirect (or fully baked)
|
||||
lighting to a scene. Unlike the :ref:`VoxelGI <doc_using_voxel_gi>` and
|
||||
:ref:`SDFGI <doc_sdfgi>` approaches, baked lightmaps work fine on low-end PCs
|
||||
and mobile devices, as they consume almost no resources at run-time. Also unlike
|
||||
VoxelGI and SDFGI, baked lightmaps can optionally be used to store direct
|
||||
lighting, which provides even further performance gains.
|
||||
|
||||
Unlike VoxelGI and SDFGI, baked lightmaps are completely static. Once baked, they
|
||||
can't be modified at all. They also don't provide the scene with reflections, so
|
||||
using :ref:`doc_reflection_probes` together with it on interiors (or using a Sky
|
||||
on exteriors) is a requirement to get good quality.
|
||||
|
||||
As they are baked, they have fewer problems than VoxelGI and SDFGI regarding
|
||||
light bleeding, and indirect light will often look better. The downside is that
|
||||
baking lightmaps takes longer compared to baking VoxelGI. While baking VoxelGI
|
||||
can be done in a matter of seconds, baking lightmaps can take several minutes if
|
||||
not more. This can slow down iteration speed significantly, so it is recommended
|
||||
to bake lightmaps only when you actually need to see changes in lighting. Since
|
||||
Godot 4.0, lightmaps are baked on the GPU, making light baking faster if you
|
||||
have a mid-range or high-end dedicated GPU.
|
||||
|
||||
Baking lightmaps will also reserve baked materials' UV2 slot, which means you can
|
||||
no longer use it for other purposes in materials (either in the built-in
|
||||
:ref:`doc_standard_material_3d` or in custom shaders).
|
||||
|
||||
Despite their lack of flexibility, baked lightmaps typically offer both the best
|
||||
quality *and* performance at the same time in (mostly) static scenes. This makes
|
||||
lightmaps still popular in game development, despite lightmaps being the
|
||||
oldest technique for global illumination in video games.
|
||||
|
||||
.. seealso::
|
||||
|
||||
Not sure if LightmapGI is suited to your needs?
|
||||
See :ref:`doc_introduction_to_global_illumination_comparison`
|
||||
for a comparison of GI techniques available in Godot 4.
|
||||
|
||||
Visual comparison
|
||||
-----------------
|
||||
|
||||
.. figure:: img/gi_none.webp
|
||||
:alt: LightmapGI disabled.
|
||||
|
||||
LightmapGI disabled.
|
||||
|
||||
.. figure:: img/gi_lightmap_gi_indirect_only.webp
|
||||
:alt: LightmapGI enabled (with indirect light baked only).
|
||||
|
||||
LightmapGI enabled (with indirect light baked only). Direct light is still
|
||||
real-time, allowing for subtle changes during gameplay.
|
||||
|
||||
.. figure:: img/gi_lightmap_gi_direct_and_indirect.webp
|
||||
:alt: LightmapGI enabled (with direct and indirect light baked).
|
||||
|
||||
LightmapGI enabled (with direct and indirect light baked). Best performance,
|
||||
but lower quality visuals. Notice the blurrier sun shadow in the top-right
|
||||
corner.
|
||||
|
||||
Visual comparison
|
||||
-----------------
|
||||
|
||||
Here are some comparisons of how LightmapGI vs. VoxelGI look. Notice that
|
||||
lightmaps are more accurate, but also suffer from the fact
|
||||
that lighting is on an unwrapped texture, so transitions and resolution may not
|
||||
be that good. VoxelGI looks less accurate (as it's an approximation), but
|
||||
smoother overall.
|
||||
|
||||
.. image:: img/lightmap_gi_comparison.png
|
||||
|
||||
SDFGI is also less accurate compared to LightmapGI. However, SDFGI can support
|
||||
large open worlds without any need for baking.
|
||||
|
||||
Setting up
|
||||
----------
|
||||
|
||||
First of all, before the lightmapper can do anything, the objects to be baked need
|
||||
an UV2 layer and a texture size. An UV2 layer is a set of secondary texture coordinates
|
||||
that ensures any face in the object has its own place in the UV map. Faces must
|
||||
not share pixels in the texture.
|
||||
|
||||
There are a few ways to ensure your object has a unique UV2 layer and texture size:
|
||||
|
||||
Unwrap on scene import (recommended)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In most scenarios, this is the best approach to use. The only downside is that,
|
||||
on large models, unwrapping can take a while on import. Nonetheless, Godot will
|
||||
cache the UV2 across reimports, so it will only be regenerated when needed.
|
||||
|
||||
Select the imported scene in the filesystem dock, then go to the **Import** dock.
|
||||
There, the following option can be modified:
|
||||
|
||||
.. image:: img/lightmap_gi_import.webp
|
||||
|
||||
The **Meshes > Light Baking** option must be set to **Static Lightmaps (VoxelGI/SDFGI/LightmapGI)**:
|
||||
|
||||
.. image:: img/lightmap_gi_mesh_import_meshes.webp
|
||||
|
||||
When unwrapping on import, you can adjust the texture size using the **Meshes > Lightmap
|
||||
Texel Size** option. *Lower* values will result in more detailed lightmaps,
|
||||
possibly resulting in higher visual quality at the cost of longer bake times and
|
||||
larger lightmap file sizes. The default value of ``0.2`` is suited for
|
||||
small/medium-sized scenes, but you may want to increase it to ``0.5`` or even
|
||||
more for larger scenes. This is especially the case if you're baking indirect
|
||||
lighting only, as indirect light is low-frequency data (which means it doesn't
|
||||
need high-resolution textures to be accurately represented).
|
||||
|
||||
The effect of setting this option is that all meshes within the scene will have
|
||||
their UV2 maps properly generated.
|
||||
|
||||
.. warning::
|
||||
|
||||
When reusing a mesh within a scene, keep in mind that UVs will be generated
|
||||
for the first instance found. If the mesh is re-used with different scales
|
||||
(and the scales are wildly different, more than half or twice), this will
|
||||
result in inefficient lightmaps. To avoid this, adjust the **Lightmap
|
||||
Scale** property in the GeometryInstance3D section of a MeshInstance3D node.
|
||||
This lets you *increase* the level of lightmap detail for specific
|
||||
MeshInstance3D nodes (but not decrease it).
|
||||
|
||||
Also, the ``*.unwrap_cache`` files should *not* be ignored in version control
|
||||
as these files guarantee that UV2 reimports are consistent across platforms
|
||||
and engine versions.
|
||||
|
||||
Unwrap from within Godot
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. warning::
|
||||
|
||||
If this Mesh menu operation is used on an imported 3D scene, the generated
|
||||
UV2 will be lost when the scene is reloaded.
|
||||
|
||||
Godot has an option to unwrap meshes and visualize the UV channels. After
|
||||
selecting a MeshInstance3D node, it can be found in the **Mesh** menu at the top
|
||||
of the 3D editor viewport:
|
||||
|
||||
.. image:: img/lightmap_gi_mesh_menu.png
|
||||
|
||||
This will generate a second set of UV2 coordinates which can be used for baking.
|
||||
It will also set the texture size automatically.
|
||||
|
||||
Unwrap from your 3D DCC
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The last option is to do it from your favorite 3D app. This approach is
|
||||
generally **not recommended**, but it's explained so that you know it exists.
|
||||
The main advantage is that, on complex objects that you may want to re-import a
|
||||
lot, the texture generation process can be quite costly within Godot, so having
|
||||
it unwrapped before import can be faster.
|
||||
|
||||
Simply do an unwrap on the second UV2 layer.
|
||||
|
||||
.. image:: img/lightmap_gi_blender.png
|
||||
|
||||
Then import the 3D scene normally. Remember you will need to set the texture
|
||||
size on the mesh after import.
|
||||
|
||||
.. image:: img/lightmap_gi_lmsize.png
|
||||
|
||||
If you use external meshes on import, the size will be kept.
|
||||
Be wary that most unwrappers in 3D DCCs are not quality oriented, as they are
|
||||
meant to work quickly. You will mostly need to use seams or other techniques to
|
||||
create better unwrapping.
|
||||
|
||||
Checking UV2
|
||||
^^^^^^^^^^^^
|
||||
|
||||
In the **Mesh** menu mentioned before, the UV2 texture coordinates can be visualized.
|
||||
If something is failing, double-check that the meshes have these UV2 coordinates:
|
||||
|
||||
.. image:: img/lightmap_gi_uvchannel.png
|
||||
|
||||
Setting up the scene
|
||||
--------------------
|
||||
|
||||
Before anything is done, a **LightmapGI** node needs to be added to a scene.
|
||||
This will enable light baking on all nodes (and sub-nodes) in that scene, even
|
||||
on instanced scenes.
|
||||
|
||||
.. image:: img/lightmap_gi_scene.png
|
||||
|
||||
A sub-scene can be instanced several times, as this is supported by the baker.
|
||||
Each instance will be assigned a lightmap of its own. To avoid issues with
|
||||
inconsistent lightmap texel scaling, make sure to respect the rule about mesh
|
||||
scaling mentioned before.
|
||||
|
||||
Setting up meshes
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
For a **MeshInstance3D** node to take part in the baking process, it needs to have
|
||||
its bake mode set to **Static**. Meshes that have their bake mode set to **Disabled**
|
||||
or **Dynamic** will be ignored by the lightmapper.
|
||||
|
||||
.. image:: img/lightmap_gi_use.png
|
||||
|
||||
When auto-generating lightmaps on scene import, this is enabled automatically.
|
||||
|
||||
Setting up lights
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Lights are baked with indirect light only by default. This means that shadowmapping
|
||||
and lighting are still dynamic and affect moving objects, but light bounces from
|
||||
that light will be baked.
|
||||
|
||||
Lights can be disabled (no bake) or be fully baked (direct and indirect). This
|
||||
can be controlled from the **Bake Mode** menu in lights:
|
||||
|
||||
.. image:: img/lightmap_gi_bake_mode.png
|
||||
|
||||
The modes are:
|
||||
|
||||
Disabled
|
||||
^^^^^^^^
|
||||
|
||||
The light is ignored when baking lightmaps. Keep in mind hiding a light will have
|
||||
no effect for baking, so this must be used instead of hiding the Light node.
|
||||
|
||||
This is the mode to use for dynamic lighting effects such as explosions and weapon effects.
|
||||
|
||||
Dynamic
|
||||
^^^^^^^
|
||||
|
||||
This is the default mode, and is a compromise between performance and real-time
|
||||
friendliness. Only indirect lighting will be baked. Direct light and shadows are
|
||||
still real-time, as they would be without LightmapGI.
|
||||
|
||||
This mode allows performing *subtle* changes to a light's color, energy and
|
||||
position while still looking fairly correct. For example, you can use this
|
||||
to create flickering static torches that have their indirect light baked.
|
||||
|
||||
Static
|
||||
^^^^^^
|
||||
|
||||
Both indirect and direct lighting will be baked. Since static surfaces can skip
|
||||
lighting and shadow computations entirely, this mode provides the best
|
||||
performance along with smooth shadows that never fade based on distance. The
|
||||
real-time light will not affect baked surfaces anymore, but it will still affect
|
||||
dynamic objects. When using the **All** bake mode on a light, dynamic objects
|
||||
will not cast real-time shadows onto baked surfaces, so you need to use a
|
||||
different approach such as blob shadows instead. Blob shadows can be implemented
|
||||
with a Decal node.
|
||||
|
||||
The light will not be adjustable at all during gameplay. Moving the light or
|
||||
changing its color (or energy) will not have any effect on static surfaces.
|
||||
|
||||
Since bake modes can be adjusted on a per-light basis, it is possible to create
|
||||
hybrid baked light setups. One popular option is to use a real-time
|
||||
DirectionalLight with its bake mode set to **Dynamic**, and use the **Static**
|
||||
bake mode for OmniLights and SpotLights. This provides good performance while
|
||||
still allowing dynamic objects to cast real-time shadows in outdoor areas.
|
||||
|
||||
Fully baked lights can also make use of light nodes' **Size** (omni/spot) or
|
||||
**Angular Distance** (directional) properties. This allows for shadows with
|
||||
realistic penumbra that increases in size as the distance between the caster and
|
||||
the shadow increases. This also has a lower performance cost compared to
|
||||
real-time PCSS shadows, as only dynamic objects have real-time shadows rendered
|
||||
on them.
|
||||
|
||||
.. image:: img/lightmap_gi_omnilight_size.png
|
||||
|
||||
Baking
|
||||
------
|
||||
|
||||
To begin the bake process, click the **Bake Lightmaps** button at the top of the
|
||||
3D editor viewport when selecting the LightmapGI node:
|
||||
|
||||
.. image:: img/lightmap_gi_bake.png
|
||||
|
||||
This can take from seconds to minutes (or hours) depending on scene size, bake
|
||||
method and quality selected.
|
||||
|
||||
Tweaks
|
||||
^^^^^^
|
||||
|
||||
- **Quality:** Four bake quality modes are provided: Low, Medium, High, and
|
||||
Ultra. Higher quality takes more time, but result in a better-looking lightmap
|
||||
with less noise. The difference is especially noticeable with emissive
|
||||
materials or areas that get little to no direct lighting. Each bake quality
|
||||
mode can be further adjusted in the Project Settings.
|
||||
- **Bounces:** The number of bounces to use for indirect lighting. The default
|
||||
value (``3``) is a good compromise between bake times and quality. Higher
|
||||
values will make light bounce around more times before it stops, which makes
|
||||
indirect lighting look smoother (but also brighter). During the initial
|
||||
lighting iteration work, it is recommended to decrease the number of bounces
|
||||
to ``1`` to speed up baking. Remember that your scene will be darker when
|
||||
decreasing the number of bounces.
|
||||
- **Directional:** If enabled, stores directional information for lightmaps.
|
||||
This improves normal mapped materials' appearance for baked surfaces,
|
||||
especially with fully baked lights (since they also have direct light baked).
|
||||
The downside is that directional lightmaps are slightly more expensive to render.
|
||||
They also require more time to bake and result in larger file sizes.
|
||||
- **Interior:** If enabled, environment lighting will not be sourced. Use this
|
||||
for purely indoor scenes to avoid light leaks.
|
||||
- **Use Denoiser:** If enabled, uses `OpenImageDenoise <https://www.openimagedenoise.org/>`__
|
||||
to make the lightmap significantly less noisy. This increases bake times and can
|
||||
occasionally introduce artifacts, but the result is often worth it.
|
||||
**All** bake mode on a light, this will turn colored lighting into grayscale
|
||||
lighting. This can be disabled together with HDR to get the smallest possible
|
||||
lightmap file at a given resolution.
|
||||
- **Bias:** The offset value to use for shadows in 3D units. You generally don't
|
||||
need to change this value, except if you run into issues with light bleeding or
|
||||
dark spots in your lightmap after baking. This setting does not affect real-time
|
||||
shadows casted on baked surfaces (for lights with **Dynamic** bake mode).
|
||||
- **Max Texture Size:** The maximum texture size for the generated texture
|
||||
atlas. Higher values will result in fewer slices being generated, but may not
|
||||
work on all hardware as a result of hardware limitations on texture sizes.
|
||||
Leave this at its default value of ``16384`` if unsure.
|
||||
- **Environment > Mode:** Controls how environment lighting is sourced when
|
||||
baking lightmaps. The default value of **Scene** is suited for levels with
|
||||
visible exterior parts. For purely indoor scenes, set this to **Disabled** to
|
||||
avoid light leaks and speed up baking. This can also be set to **Custom Sky**
|
||||
or **Custom Color** to use environment lighting that differs from the actual
|
||||
scene's environment sky.
|
||||
- **Gen Probes > Subdiv:** See :ref:`doc_using_lightmap_gi_dynamic_objects`.
|
||||
- **Data > Light Data:** See :ref:`doc_using_lightmap_gi_data`.
|
||||
|
||||
Balancing bake times with quality
|
||||
---------------------------------
|
||||
|
||||
Since high-quality bakes can take very long (up to dozens of minutes for large
|
||||
complex scenes), it is recommended to use lower quality settings at first. Then,
|
||||
once you are confident with your scene's lighting setup, raise the quality
|
||||
settings and perform a "final" bake before exporting your project.
|
||||
|
||||
Reducing the lightmap resolution by increasing **Lightmap Texel Size** on the
|
||||
imported 3D scenes will also speed up baking significantly. However, this will
|
||||
require you to reimport all lightmapped 3D scenes before you can bake lightmaps
|
||||
again.
|
||||
|
||||
.. _doc_using_lightmap_gi_dynamic_objects:
|
||||
|
||||
Dynamic objects
|
||||
---------------
|
||||
|
||||
Unlike VoxelGI and SDFGI, dynamic objects receive indirect lighting differently
|
||||
compared to static objects. This is because lightmapping is only performed on
|
||||
static objects.
|
||||
|
||||
To display indirect lighting on dynamic objects, a 3D probe system is used, with
|
||||
light probes being spread throughout the scene. When baking lightmaps, the
|
||||
lightmapper will calculate the amount of *indirect* light received by the probe.
|
||||
Direct light is not stored within light probes, even for lights that have their
|
||||
bake mode set to **Static** (as dynamic objects continue to be lit in
|
||||
real-time).
|
||||
|
||||
There are 2 ways to add light probes to a scene:
|
||||
|
||||
- **Automatic:** Set **Gen Probes > Subdiv** to a value other than **Disabled**,
|
||||
then bake lightmaps. The default is ``8``, but you can choose a greater value
|
||||
to improve precision at the cost of longer bake times and larger output file
|
||||
size.
|
||||
- **Manual:** In addition or as an alternative to generating probes
|
||||
automatically, you can add light probes manually by adding LightmapProbe nodes
|
||||
to the scene. This can be used to improve lighting detail in areas frequently
|
||||
travelled by dynamic objects.
|
||||
|
||||
.. _doc_using_lightmap_gi_data:
|
||||
|
||||
Lightmap data
|
||||
-------------
|
||||
|
||||
The **Data > Light Data** property in the LightmapGI node contains the lightmap
|
||||
data after baking. Textures are saved to disk, but this also contains the
|
||||
capture data for dynamic objects, which can be heavy. If you are using a scene
|
||||
in ``.tscn`` format, you should save this resource to an external binary
|
||||
``.lmbake`` file to avoid bloating the ``.tscn`` scene with binary data encoded
|
||||
in Base64.
|
||||
|
||||
.. tip::
|
||||
|
||||
The generated EXR file can be viewed and even edited using an image editor
|
||||
to perform post-processing if needed. However, keep in mind that changes to
|
||||
the EXR file will be lost when baking lightmaps again.
|
||||
195
tutorials/3d/using_voxel_gi.rst
Normal file
@@ -0,0 +1,195 @@
|
||||
.. _doc_using_voxel_gi:
|
||||
|
||||
Using Voxel global illumination
|
||||
===============================
|
||||
|
||||
VoxelGI is a form of fully real-time global illumination, intended to be used
|
||||
for small/medium-scale 3D scenes. VoxelGI is fairly demanding on the GPU, so
|
||||
it's best used when targeting dedicated graphics cards.
|
||||
|
||||
.. important::
|
||||
|
||||
VoxelGI is only supported when using the Forward Plus rendering backend,
|
||||
not the Forward Mobile or Compatibility backends.
|
||||
|
||||
.. seealso::
|
||||
|
||||
Not sure if VoxelGI is suited to your needs?
|
||||
See :ref:`doc_introduction_to_global_illumination_comparison`
|
||||
for a comparison of GI techniques available in Godot 4.
|
||||
|
||||
Visual comparison
|
||||
-----------------
|
||||
|
||||
.. figure:: img/gi_none.webp
|
||||
:alt: VoxelGI disabled.
|
||||
|
||||
VoxelGI disabled.
|
||||
|
||||
.. figure:: img/gi_voxel_gi.webp
|
||||
:alt: VoxelGI enabled.
|
||||
|
||||
VoxelGI enabled.
|
||||
|
||||
Setting up VoxelGI
|
||||
------------------
|
||||
|
||||
1. Make sure your static level geometry is imported with the Light Baking option
|
||||
set to **Static** or **Static Lightmaps** in the Import dock.
|
||||
For manually added MeshInstance3D nodes, make sure the **Global Illumination > Mode**
|
||||
property is set to **Static** in the inspector.
|
||||
2. Create a VoxelGI node in the Scene tree dock.
|
||||
3. Move the VoxelGI node to the center of the area you want it to cover by
|
||||
dragging the manipulation gizmo in the 3D viewport. Then adjust the VoxelGI's
|
||||
extents by dragging the red points in the 3D viewport (or enter values in the
|
||||
inspector). Make sure the VoxelGI's extents aren't unnecessarily large, or
|
||||
quality will suffer.
|
||||
4. Select the VoxelGI node and click **Bake** at the top of the 3D editor viewport.
|
||||
This will take at least a few seconds to complete (depending on the number of VoxelGI
|
||||
subdivisions and scene complexity).
|
||||
|
||||
If at least one mesh contained within the VoxelGI's extents has its global
|
||||
illumination mode set to **Static**, you should see indirect lighting appear
|
||||
within the scene.
|
||||
|
||||
.. note::
|
||||
|
||||
To avoid bloating text-based scene files with large amounts of binary data,
|
||||
make sure the VoxelGIData resource is *always* saved to an external binary file.
|
||||
This file must be saved with a ``.res`` (binary resource) extension instead of
|
||||
``.tres`` (text-based resource).
|
||||
Using an external binary resource for VoxelGIData will keep your text-based
|
||||
scene small while ensuring it loads and saves quickly.
|
||||
|
||||
VoxelGI node properties
|
||||
-----------------------
|
||||
|
||||
The following properties can be adjusted in the VoxelGI node inspector before
|
||||
baking:
|
||||
|
||||
- **Subdiv:** Higher values result in more precise indirect lighting, at the cost
|
||||
of lower performance, longer bake times and increased storage requirements.
|
||||
- **Extents:** Represents the size of the box in which indirect lighting should
|
||||
be baked. Extents are centered around the VoxelGI node's origin.
|
||||
|
||||
The following properties can be adjusted in the VoxelGIData *resource* that is
|
||||
contained within a VoxelGI node after it has been baked:
|
||||
|
||||
- **Dynamic Range:** The maximum brightness that can be represented in indirect lighting.
|
||||
Higher values make it possible to represent brighter indirect light,
|
||||
at the cost of lower precision (which can result in visible banding).
|
||||
If in doubt, leave this unchanged.
|
||||
- **Energy:** The indirect lighting's overall energy. This also effects the energy
|
||||
of direct lighting emitted by meshes with emissive materials.
|
||||
- **Bias:** Optional bias added to lookups into the voxel buffer at run time.
|
||||
This helps avoid self-occlusion artifacts.
|
||||
- **Normal Bias:** Similar to **Bias**, but offsets the lookup into the voxel buffer
|
||||
by the surface normal. This also helps avoid self-occlusion artifacts. Higher
|
||||
values reduce self-reflections visible in non-rough materials, at the cost of
|
||||
more visible light leaking and flatter-looking indirect lighting. To
|
||||
prioritize hiding self-reflections over lighting quality, set **Bias** to
|
||||
``0.0`` and **Normal Bias** to a value between ``1.0`` and ``2.0``.
|
||||
- **Propagation:** The energy factor to use for bounced indirect lighting.
|
||||
Higher values will result in brighter, more diffuse lighting
|
||||
(which may end up looking too flat). When **Use Two Bounces** is enabled,
|
||||
you may want to decrease **Propagation** to compensate for the overall brighter
|
||||
indirect lighting.
|
||||
- **Use Two Bounces:** If enabled, lighting will bounce twice instead of just once.
|
||||
This results in more realistic-looking indirect lighting, and makes indirect lighting
|
||||
visible in reflections as well. Enabling this generally has no noticeable performance cost.
|
||||
- **Interior:** If enabled, environment sky lighting will not be taken into account by VoxelGI.
|
||||
This should be enabled in indoor scenes to avoid light leaking from the environment.
|
||||
|
||||
VoxelGI interaction with lights and objects
|
||||
-------------------------------------------
|
||||
|
||||
To ensure correct visuals when using VoxelGI, you must configure your meshes
|
||||
and lights' global illumination properties according to their *purpose* in the
|
||||
scene (static or dynamic).
|
||||
|
||||
There are 3 global illumination modes available for meshes:
|
||||
|
||||
- **Disabled:** The mesh won't be taken into account for VoxelGI baking.
|
||||
The mesh will *receive* indirect lighting from the scene, but it will not
|
||||
*contribute* indirect lighting to the scene.
|
||||
- **Static (default):** The mesh will be taken into account for VoxelGI baking. The mesh will
|
||||
both receive *and* contribute indirect lighting to the scene. If the mesh
|
||||
is changed in any way after baking, the VoxelGI node must be baked again.
|
||||
Otherwise, indirect lighting will look incorrect.
|
||||
- **Dynamic:** The mesh won't be taken into account for VoxelGI baking, but it will
|
||||
still receive *and* contribute indirect lighting to the scene in real-time.
|
||||
This option is much slower compared to **Static**. Only use the **Dynamic**
|
||||
global illumination mode on large meshes that will change significantly during gameplay.
|
||||
|
||||
Additionally, there are 3 bake modes available for lights
|
||||
(DirectionalLight3D, OmniLight3D and SpotLight3D):
|
||||
|
||||
- **Disabled:** The light won't be taken into account for VoxelGI baking.
|
||||
The light won't contribute indirect lighting to the scene.
|
||||
- **Static:** The light will be taken into account for VoxelGI baking.
|
||||
The light will contribute indirect lighting to the scene. If the light
|
||||
is changed in any way after baking, the VoxelGI node must be baked again or
|
||||
indirect lighting will look incorrect. If in doubt, use this mode for level lighting.
|
||||
- **Dynamic (default):** The light won't be taken into account for VoxelGI baking,
|
||||
but it will still contribute indirect lighting to the scene in real-time.
|
||||
This option is slower compared to **Static**. Only use the **Dynamic** global
|
||||
illumination mode on lights that will change significantly during gameplay.
|
||||
|
||||
.. note::
|
||||
|
||||
The amount of indirect energy emitted by a light depends on its color,
|
||||
energy *and* indirect energy properties. To make a specific light emit more
|
||||
or less indirect energy without affecting the amount of direct light emitted
|
||||
by the light, adjust the **Indirect Energy** property in the Light3D inspector.
|
||||
|
||||
.. seealso::
|
||||
|
||||
See :ref:`doc_introduction_to_global_illumination_gi_mode_recommendations`
|
||||
for general usage recommendations.
|
||||
|
||||
Adjusting VoxelGI performance and quality
|
||||
-----------------------------------------
|
||||
|
||||
Since VoxelGI is relatively demanding, it will perform best on systems with recent
|
||||
dedicated GPUs. On older dedicated GPUs and integrated graphics,
|
||||
tweaking the settings is necessary to achieve reasonable performance.
|
||||
|
||||
In the Project Settings' **Rendering > Global Illumination** section,
|
||||
VoxelGI quality can also be adjusted in two ways:
|
||||
|
||||
- **Voxel Gi > Quality:** If set to **Low**
|
||||
instead of **High**, voxel cone tracing will only use 4 taps instead of 6.
|
||||
This speeds up rendering at the cost of less pronounced ambient occlusion.
|
||||
- **Gi > Use Half Resolution:** If enabled, both VoxelGI and SDFGI will have
|
||||
their GI buffer rendering at halved resolution. For instance, when rendering
|
||||
in 3840×2160, the GI buffer will be computed at a 1920×1080 resolution.
|
||||
Enabling this option saves a lot of GPU time, but it can introduce visible
|
||||
aliasing around thin details.
|
||||
|
||||
Note that the **Advanced** toggle must be enabled in the project settings dialog
|
||||
for the above settings to be visible.
|
||||
|
||||
Additionally, VoxelGI can be disabled entirely by hiding the VoxelGI node.
|
||||
This can be used for comparison purposes or to improve performance on low-end systems.
|
||||
|
||||
Reducing VoxelGI light leaks and artifacts
|
||||
------------------------------------------
|
||||
|
||||
After baking VoxelGI, you may notice indirect light is leaking at some spots
|
||||
in your level geometry. This can be remedied in several ways:
|
||||
|
||||
- For both light leaking and artifacts, try moving or rotating the VoxelGI node
|
||||
then bake it again.
|
||||
- To combat light leaking in general, ensure your level geometry is fully sealed.
|
||||
This is best done in the 3D modeling software used to design the level,
|
||||
but primitive MeshInstance3D nodes with their global illumination mode set to
|
||||
**Static** can also be used.
|
||||
- To combat light leaking with thin geometry, it's recommended to make the geometry
|
||||
in question thicker. If this is not possible, then add a primitive MeshInstance3D
|
||||
node with its global illumination mode set to **Static**. Bake VoxelGI again,
|
||||
then hide the primitive MeshInstance3D node (it will still be taken into account by VoxelGI).
|
||||
For optimal results, the MeshInstance3D should have a material whose color
|
||||
matches the original thin geometry.
|
||||
- To combat artifacts that can appear on reflective surfaces, try increasing
|
||||
**Bias** and/or **Normal Bias** in the VoxelGIData resource as described above.
|
||||
Do not increase these values too high, or light leaking will become more pronounced.
|
||||
@@ -281,7 +281,7 @@ Whether or not the mesh is used in baked lightmaps.
|
||||
- **Enable:** The mesh is used in baked lightmaps.
|
||||
- **Gen Lightmaps:** The mesh is used in baked lightmaps, and unwraps a second UV layer for lightmaps.
|
||||
|
||||
.. note:: For more information on light baking see :ref:`doc_baked_lightmaps`.
|
||||
.. note:: For more information on light baking see :ref:`doc_using_lightmap_gi`.
|
||||
|
||||
External Files
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
@@ -618,7 +618,7 @@ converter doesn't support updating existing setups:
|
||||
+=====================+=======================+============================================================================+
|
||||
| AnimationTreePlayer | AnimationTree | AnimationTreePlayer was deprecated since Godot 3.1. |
|
||||
+---------------------+-----------------------+----------------------------------------------------------------------------+
|
||||
| BakedLightmap | LightmapGI | See :ref:`doc_baked_lightmaps`. |
|
||||
| BakedLightmap | LightmapGI | See :ref:`doc_using_lightmap_gi`. |
|
||||
+---------------------+-----------------------+ |
|
||||
| BakedLightmapData | LightmapGIData | |
|
||||
+---------------------+-----------------------+----------------------------------------------------------------------------+
|
||||
|
||||
@@ -126,7 +126,7 @@ but has the downside that it will not be dynamic. Sometimes, this is a trade-off
|
||||
worth making.
|
||||
|
||||
In general, if several lights need to affect a scene, it's best to use
|
||||
:ref:`doc_baked_lightmaps`. Baking can also improve the scene quality by adding
|
||||
:ref:`doc_using_lightmap_gi`. Baking can also improve the scene quality by adding
|
||||
indirect light bounces.
|
||||
|
||||
Animation and skinning
|
||||
|
||||