Revamp global illumination documentation

- Add an introduction page with an explanation and comparison table.
- Add a page on faking global illumination.
This commit is contained in:
Hugo Locurcio
2021-10-06 20:36:41 +02:00
parent 229a7c78f6
commit 6e453527b1
48 changed files with 1450 additions and 600 deletions

View File

@@ -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
-------------

View File

@@ -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

View 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

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

BIN
tutorials/3d/img/bad.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

BIN
tutorials/3d/img/good.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 151 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 587 KiB

After

Width:  |  Height:  |  Size: 587 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

View File

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@@ -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

View 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.

View File

@@ -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

View File

@@ -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
View 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.

View File

@@ -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

View 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.

View 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.

View File

@@ -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
~~~~~~~~~~~~~~

View File

@@ -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 | |
+---------------------+-----------------------+----------------------------------------------------------------------------+

View File

@@ -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