mirror of
https://github.com/godotengine/godot-docs.git
synced 2026-09-03 18:14:53 +03:00
Merge pull request #11816 from Calinou/lights-and-shadows-add-area-lights
Add documentation for area lights in 3D lights and shadows
This commit is contained in:
@@ -498,6 +498,10 @@ planned in a future release.
|
||||
Clustering is also used for reflection probes and decal rendering in the
|
||||
Forward+ renderer.
|
||||
|
||||
Area lights make use of the
|
||||
`Linearly Transformed Cosines <https://eheitzresearch.wordpress.com/757-2/>`__
|
||||
technique.
|
||||
|
||||
Shadow mapping
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
BIN
tutorials/3d/img/lights_and_shadows_area_example.webp
Normal file
BIN
tutorials/3d/img/lights_and_shadows_area_example.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 122 KiB |
BIN
tutorials/3d/img/lights_and_shadows_area_texture.webp
Normal file
BIN
tutorials/3d/img/lights_and_shadows_area_texture.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 201 KiB |
@@ -373,6 +373,87 @@ With the projector texture below, the following result is obtained:
|
||||
working entirely. If you need shadows for wider lights, use an omni light
|
||||
instead.
|
||||
|
||||
Area light
|
||||
----------
|
||||
|
||||
Sometimes, you want lighting to come from a large area instead of a single
|
||||
point. Area lights are useful for simulating soft, diffuse lighting, such as
|
||||
light coming from a window or a lit billboard. This type of light is expensive
|
||||
to render in real-time, so it should be used sparingly, especially when shadows
|
||||
are enabled.
|
||||
|
||||
Godot provides the :ref:`class_AreaLight3D` node for this purpose, which emits
|
||||
light from a rectangular area. The node only emits light and has no other visual
|
||||
representation in the scene. The screenshots below use a :ref:`class_Sprite3D`
|
||||
node as a child of the area light for visualization purposes.
|
||||
|
||||
Area lights can also cast shadows, with variable penumbra simulated using
|
||||
:ref:`PCSS <doc_lights_and_shadows_pcss_recommendations>` by default. The size
|
||||
of this penumbra can be controlled with the Light3D **Size** property. This
|
||||
effect can be quite demanding, so it can be turned off by setting **Size** to
|
||||
``0.0``.
|
||||
|
||||
.. image:: img/lights_and_shadows_area_example.webp
|
||||
|
||||
.. note::
|
||||
|
||||
Since area lights are difficult to simulate in a real-time rasterized
|
||||
renderer, they come with a number of limitations.
|
||||
|
||||
For small light sources, you will likely get better results when using point
|
||||
lights. Shadows from area lights are crude approximations, as they are
|
||||
calculated as if they were point lights, and may appear to be distorted at
|
||||
the edges. To get a better result, make sure the meshes in the light's range
|
||||
are sufficiently subdivided.
|
||||
|
||||
Area lights suffer from light leaking on the backside of geometry closely in
|
||||
front of them at grazing angles, so be careful with where you place them.
|
||||
|
||||
Lastly, not all material features are fully supported; area lights are
|
||||
practically limited to Lambertian diffuse and GGX specular shading, while
|
||||
anisotropic materials will appear as if isotropic. Vertex shading is also
|
||||
not implemented for area lights.
|
||||
|
||||
Area lights emit light in a rectangular area defined by the **Area > Size**
|
||||
property (not to be confused with the generic Light3D **Size** property). To get
|
||||
a physically accurate result, you should resize this area to match the size of
|
||||
the real-life light source you are trying to simulate. For example, if you are
|
||||
simulating a 1-meter neon tube that is 10 centimeters wide, set the area
|
||||
size to ``(1, 0.1)`` and adjust the energy accordingly.
|
||||
|
||||
By default, the light's energy is normalized: the larger the area, the weaker
|
||||
the light. This allows you to change the area size without needing to adjust the
|
||||
energy to compensate, which is useful for animation. You can disable this
|
||||
behavior by unchecking **Area > Normalize Energy** if you want the energy to be
|
||||
independent of the area size.
|
||||
|
||||
The rectangular area can optionally be textured. This can be effectively used to
|
||||
change the light's shape into any 2D shape, or tint it in different colors. The
|
||||
texture's alpha channel is treated as black (no light coming through). The area
|
||||
light's texture will be visible in reflections according to the surface's
|
||||
roughness. This behavior is different from omni/spot projectors, as it does not
|
||||
project the texture directly onto all diffuse lighting.
|
||||
|
||||
When using a textures that are transparent or black toward the edges, you might
|
||||
want to leave a gap of a few pixels to make sure the texture is blurred
|
||||
smoothly.
|
||||
|
||||
.. image:: img/lights_and_shadows_area_texture.webp
|
||||
|
||||
.. note::
|
||||
|
||||
Changing the area light's texture at runtime can be expensive, especially if
|
||||
the texture is large.
|
||||
|
||||
To reduce the performance impact of switching textures at runtime, make sure
|
||||
each dimension of an area texture is either a multiple of 128 pixels, or a
|
||||
power of two. This removes the need for a scaling pass, which slows down
|
||||
texture changes. The textures don't necessarily have to be square to be
|
||||
optimal. Examples of optimal texture sizes include 32×64, 128×128, and
|
||||
256×384.
|
||||
|
||||
Textured area lights are not supported in the Compatibility renderer.
|
||||
|
||||
.. _doc_lights_and_shadows_shadow_atlas:
|
||||
|
||||
Shadow atlas
|
||||
|
||||
@@ -552,7 +552,14 @@ Below is an example of a custom ``light()`` function using a Lambertian lighting
|
||||
.. code-block:: glsl
|
||||
|
||||
void light() {
|
||||
DIFFUSE_LIGHT += clamp(dot(NORMAL, LIGHT), 0.0, 1.0) * ATTENUATION * LIGHT_COLOR / PI;
|
||||
if (LIGHT_IS_AREA) {
|
||||
// Area light GGX shading.
|
||||
DIFFUSE_LIGHT += LIGHT_AREA_DIFFUSE_MULTIPLIER * ATTENUATION * LIGHT_COLOR;
|
||||
SPECULAR_LIGHT += LIGHT_AREA_SPECULAR_MULTIPLIER * ATTENUATION * LIGHT_COLOR * SPECULAR_AMOUNT;
|
||||
} else {
|
||||
// Used for all other light types (directional, omni, spot).
|
||||
DIFFUSE_LIGHT += clamp(dot(NORMAL, LIGHT), 0.0, 1.0) * ATTENUATION * LIGHT_COLOR / PI;
|
||||
}
|
||||
}
|
||||
|
||||
If you want the lights to add together, add the light contribution to ``DIFFUSE_LIGHT`` using ``+=``, rather than overwriting it.
|
||||
|
||||
Reference in New Issue
Block a user