Update the 2D lights and shadows page for Godot 4.0 (#6424)

This commit is contained in:
Hugo Locurcio
2022-12-17 19:23:34 +01:00
committed by GitHub
parent 2b9d539ed2
commit 4431a725fe
10 changed files with 267 additions and 170 deletions
+267 -170
View File
@@ -6,238 +6,335 @@
Introduction
------------
This tutorial explains how the 2D lighting works in the
`lights and shadows <https://github.com/godotengine/godot-demo-projects/tree/master/2d/lights_and_shadows>`_ demo project.
It begins with a brief description of the resources used in the final demo and then describes how
to make a scene like the demo step by step.
By default, 2D scenes in Godot are unshaded, with no lights and shadows visible.
While this is fast to render, unshaded scenes can look bland. Godot provides the
ability to use real-time 2D lighting and shadows, which can greatly enhance the
sense of depth in your project.
.. image:: img/light_shadow_main.png
.. figure:: img/2d_lights_and_shadows_disabled.webp
:align: center
:alt: No 2D lights or shadows, scene is unshaded
All the resources for this tutorial can be found in the `official demo repository <https://github.com/godotengine/godot-demo-projects>`_
on GitHub. I suggest you download it before starting. Alternatively,
it can be downloaded from the Project Manager. Launch Godot and in the top
bar select "Templates" and search for "2D Lights and Shadows Demo".
No 2D lights or shadows, scene is unshaded
Setup
-----
.. figure:: img/2d_lights_and_shadows_enabled_no_shadows.webp
:align: center
:alt: 2D lights enabled (without shadows)
For this demo we use four textures: two for the lights, one for the shadow casters,
and one for the background. I've included links to them all here if you want to download them
separately from the demo.
2D lights enabled (without shadows)
The first is the background image (`background.png <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/background.png>`_)
used in the demo. You do not necessarily need a background, but we use one for the demo.
The second is a plain black image (`caster.png <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/caster.png>`_)
to use as our shadow caster object. For a top down game this could be a wall or any
other object that casts a shadow.
Next is the light itself (`light.png <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/light.png>`_).
If you click the link you will notice how large it is. The image you use
for a light should cover the area you want your light to cover. This image is
1024x1024 pixels, so you should use it to cover 1024x1024 pixels in your game.
Lastly, we have the spotlight image (`spot.png <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/spot.png>`_).
The demo uses a blob to show where the light is and the larger light
image to show the effect of the light upon the rest of the scene.
.. figure:: img/2d_lights_and_shadows_enabled.webp
:align: center
:alt: 2D lights and shadows enabled
2D lights and shadows enabled
Nodes
-----
The demo uses four different nodes:
* :ref:`CanvasModulate <class_CanvasModulate>`
* :ref:`Sprite2D <class_Sprite2D>`
* :ref:`PointLight2D <class_PointLight2D>`
* :ref:`LightOccluder2D <class_LightOccluder2D>`
There are several nodes involved in a complete 2D lighting setup:
:ref:`CanvasModulate <class_CanvasModulate>` is used to darken the scene.
- :ref:`CanvasModulate <class_CanvasModulate>` (to darken the rest of the scene)
- :ref:`PointLight2D <class_PointLight2D>` (for omnidirectional or spot lights)
- :ref:`DirectionalLight2D <class_PointLight2D>` (for sunlight or moonlight)
- :ref:`LightOccluder2D <class_LightOccluder2D>` (for light shadow casters)
- Other 2D nodes that receive lighting, such as Sprite2D or TileMap.
:ref:`Sprite2Ds <class_Sprite2D>` are used to display the textures for the light blobs, the
background, and for the shadow casters.
:ref:`CanvasModulate <class_CanvasModulate>` is used to darken the scene by
specifying a color that will act as the base "ambient" color. This is the final
lighting color in areas that are *not* reached by any 2D light. Without a
CanvasModulate node, the final scene would look too bright as 2D lights would
only brighten the existing unshaded appearance (which appears fully lit).
:ref:`PointLight2Ds <class_PointLight2D>` are used to light the scene. The way a light typically works
is by adding a selected texture over the rest of the scene to simulate lighting. But it can be
used in other ways, for example masking out parts of the scene.
:ref:`Sprite2Ds <class_Sprite2D>` are used to display the textures for the light
blobs, the background, and for the shadow casters.
:ref:`LightOccluder2Ds <class_LightOccluder2D>` are used to tell the shader which parts of
the scene cast shadows. The shadows appear only on areas covered by the :ref:`PointLight2D <class_PointLight2D>` and
their direction is based on the center of the :ref:`Light <class_PointLight2D>`.
:ref:`PointLight2Ds <class_PointLight2D>` are used to light the scene. The way a
light typically works is by adding a selected texture over the rest of the scene
to simulate lighting.
Lights
------
:ref:`LightOccluder2Ds <class_LightOccluder2D>` are used to tell the shader
which parts of the scene cast shadows. These occluders can be placed as
independent nodes or can be part of a TileMap node.
:ref:`Lights <class_Light2D>` cover the entire extent of their respective Texture. They use additive
blending to add the color of their texture to the scene.
The shadows appear only on areas covered by the :ref:`PointLight2D
<class_PointLight2D>` and their direction is based on the center of the
:ref:`Light <class_PointLight2D>`.
.. image:: img/light_shadow_light.png
.. note::
:ref:`Lights <class_Light2D>` have four ``Modes``: ``Add``, ``Sub``, ``Mix``, and ``Mask``.
The background color does **not** receive any lighting. If you want light to
be cast on the background, you need to add a visual representation for the
background, such as a Sprite2D.
``Add`` adds the color of the light texture to the scene. It brightens the area under the light.
The Sprite2D's **Region** properties can be helpful to quickly create a
repeating background texture, but remember to also set **Texture > Repeat** to
**Enabled** in the Sprite2D's properties.
``Sub`` subtracts the color of the light from the scene. It darkens the area under the light.
``Mix`` mixes the color of the light with the underlying scene. The resulting brightness is
halfway between the color of the light and the color underneath.
``Mask`` is used to mask out areas that are covered by the light. Masked out areas are hidden or revealed based on
the color of the light.
For the demo the lights have two components, the :ref:`Light <class_Light2D>` itself (which
is the effect of the light), and a :ref:`Sprite2D <class_Sprite2D>` blob which is an image showing the
location of the light source. A child :ref:`Sprite2D <class_Sprite2D>` is not necessary to make a
:ref:`Light <class_Light2D>` work.
.. image:: img/light_shadow_light_blob.png
Shadows
-------
Shadows are made by intersecting a :ref:`Light <class_Light2D>` with a :ref:`LightOccluder2D <class_LightOccluder2D>`.
By default shadows are turned off. To turn them on click on the :ref:`Light <class_Light2D>`
and under the Shadows section check ``Enabled``.
In the demo we are using a :ref:`Sprite2D <class_Sprite2D>` with a Texture on it to make the "Shadow Casters",
but in reality all you need is a couple of :ref:`LightOccluder2Ds <class_LightOccluder2D>`. By itself
the :ref:`LightOccluder2D <class_LightOccluder2D>` looks like a dark spot and in this demo the :ref:`Sprite2D <class_Sprite2D>` is
just a black square.
Step by step
Point lights
------------
Now that we have covered the basics of the nodes being used, we can now walk step by step through
the process of making a scene like the one found in the demo.
Point lights (also called positional lights) are the most common element in 2D
lighting. Point lights can be used to represent light from torches, fire,
projectiles, etc.
First add a :ref:`Sprite2D <class_Sprite2D>` and set its texture to the `background image <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/background.png>`_. For your game this can be any
background you choose. For this style of shadow it is most likely to be a floor texture.
PointLight2D offers the following properties to tweak in the inspector:
.. image:: img/light_shadow_background.png
- **Texture:** The texture to use as a light source. The texture's size
determines the size of the light. The texture may have an alpha channel, which
is useful when using Light2D's **Mix** blend mode, but it is not required if
using the **Add** (default) or **Subtract** blend modes.
- **Offset:** The offset for the light texture. Unlike when you move the light
node, changing the offset does *not* cause shadows to move.
- **Texture Scale:** The multiplier for the light's size. Higher values will
make the light extend out further. Larger lights have a higher performance
cost as they affect more pixels on screen, so consider this before increasing
a light's size.
- **Height:** The light's virtual height with regards to normal mapping. By
default, the light is very close to surfaces receiving lights. This will make
lighting hardly visible if normal mapping is used, so consider increasing this
value. Adjusting the light's height only makes a visible difference on
surfaces that use normal mapping.
Next create three :ref:`PointLight2D's <class_PointLight2D>` and set their textures to the `light image <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/light.png>`_. You can alter their
color in the top section. By default shadows are turned off and the ``mode`` is set to ``add``. This
means that each light adds its own color to whatever is underneath.
If you don't have a pre-made texture to use in a light, you can use this "neutral"
point light texture (right-click > **Save Image As…**):
.. image:: img/light_shadow_all_lights_no_blob.png
.. figure:: img/2d_lights_and_shadows_neutral_point_light.webp
:align: center
:alt: Neutral point light texture
Next add a child :ref:`Sprite2D <class_Sprite2D>` to each of the :ref:`Light <class_Light2D>` nodes, and set
the :ref:`Sprite2D's <class_Sprite2D>` texture to the `blob image <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/spot.png>`_. Each of these
should stay centered on the :ref:`Light <class_Light2D>` node. The blob is the image of the light
itself while the :ref:`Light <class_Light2D>` shows the effect that the light has on the scene. The
:ref:`LightOccluder2D's <class_LightOccluder2D>` which we will add later, will treat the position of the light as the center of the :ref:`Light <class_Light2D>`
node, which is why we want the blob to be centered on its parent :ref:`Light <class_Light2D>`.
Neutral point light texture
.. image:: img/light_shadow_all_lights.png
If you need different falloff you can procedurally create a texture by assigning
a **New GradientTexture2D** on the light's **Texture** property. After creating
the resource, expand its **Fill** section and set the fill mode to **Radial**.
You will then have to adjust the gradient itself to start from opaque white to
transparent white, and move its starting location to be in the center.
.. note:: The animations in the demo will not be covered here. See :ref:`doc_introduction_animation`
for information on creating animations.
Directional light
-----------------
Right now the scene should look too bright. This is because all three lights are adding color to the scene.
This is why the demo uses a :ref:`CanvasModulate <class_CanvasModulate>` in the scene. The
:ref:`CanvasModulate <class_CanvasModulate>` multiplies the entire viewport by a specific color.
New in Godot 4.0 is the ability to have directional lighting in 2D. Directional
lighting is used to represent sunlight or moonlight. Light rays are casted
parallel to each other, as if the sun or moon was infinitely far away from the
surface that is receiving the light.
Add a :ref:`CanvasModulate <class_CanvasModulate>` to the scene and set its color to ``rgb(70, 70, 70)``.
This will make the scene sufficiently dark to see the effects of the lights distinctly.
DirectionalLight2D offers the following properties:
.. image:: img/light_shadow_ambient.png
- **Height:** The light's virtual height with regards to normal mapping (``0.0``
= parallel to surfaces, ``1.0`` = perpendicular to surfaces). By default, the
light is fully parallel with the surfaces receiving lights. This will make
lighting hardly visible if normal mapping is used, so consider increasing this
value. Adjusting the light's height only makes a visual difference on surfaces
that use normal mapping. **Height** does not affect shadows' appearance.
- **Max Distance:** The maximum distance from the camera center objects can be
before their shadows are culled (in pixels). Decreasing this value can prevent
objects located outside the camera from casting shadows (while also improving
performance). Camera2D zoom is not taken into account by **Max Distance**,
which means that at higher zoom values, shadows will appear to fade out sooner
when zooming onto a given point.
Now we add the shadow casters.
.. note::
The demo uses a :ref:`Node <class_Node2D>` named "casters" to organize the shadow casters. Add a
:ref:`Node2D <class_Node2D>` to the scene. It will be used to group all the shadow casters together.
This way we can show and hide them all at the same time.
Directional shadows will always appear to be infinitely long, regardless
of the value of the **Height** property. This is a limitation of the shadow
rendering method used for 2D lights in Godot.
Each shadow caster is made of a :ref:`Sprite2D <class_Sprite2D>`, with a :ref:`LightOccluder2D <class_LightOccluder2D>`
child. For the demo the :ref:`Sprite2D <class_Sprite2D>` has a texture
set to the `caster image <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/caster.png>`_ and nothing else. The child :ref:`LightOccluder2D <class_LightOccluder2D>` is where all the magic happens. In a
game the :ref:`Sprite2D <class_Sprite2D>` could be more than a black box; it could be an image of whatever object is casting
the shadow: a wall, a magical chest, or anything else.
To have directional shadows that are not infinitely long, you should disable
shadows in the DirectionalLight2D and use a custom shader that reads from
the 2D signed distance field instead. This distance field is automatically
generated from LightOccluder2D nodes present in the scene.
.. image:: img/light_shadow_sprites.png
Common light properties
-----------------------
:ref:`LightOccluder2Ds <class_LightOccluder2D>` tell the game what shape the occluder has. They hold
an :ref:`OccluderPolygon2D <class_OccluderPolygon2D>`, which is a container
for a polygon and some other information. For this demo, since our wall is a square, we
set ``Polygon`` to a square. The other default settings are fine.
Both PointLight2D and DirectionalLight2D offer common properties, which are part
of the Light2D base class:
The first setting, ``Closed`` can be either ``on`` or ``off``. A closed polygon occludes light
coming from all directions. An open polygon only occludes light from one direction.
- **Enabled:** Allows toggling the light's visibility. Unlike hiding the light
node, disabling this property will not hide the light's children.
- **Editor Only:** If enabled, the light is only visible within the editor. It
will be automatically disabled in the running project.
- **Color:** The light's color.
- **Energy:** The light's intensity multiplier. Higher values result in a brighter light.
- **Blend Mode:** The blending formula used for light computations. The default
**Add** is suited for most use cases. **Subtract** can be used for negative
lights, which are not physically accurate but can be used for special effects.
The **Mix** blend mode mixes the value of pixels corresponding to the light's
texture with the values of pixels under it by linear interpolation.
- **Range > Z Min:** The lowest Z index affected by the light.
- **Range > Z Max:** The highest Z index affected by the light.
- **Range > Layer Min:** The lowest visual layer affected by the light.
- **Range > Layer Max:** The highest visual layer affected by the light.
- **Range > Item Cull Mask:** Controls which nodes receive light from this node,
depending on the other nodes' enabled visual layers **Occluder Light Mask**.
This can be used to prevent certain objects from receiving light.
``Cull Mode`` lets you select which direction gets culled. The default is ``Disabled``, meaning the occluder
will cast a shadow no matter which side the light is on. The other two settings ``Clockwise`` and
``Counter-Clockwise`` refer to the winding order of the vertices of the polygon. The winding order
is used to determine which side of the line is inside the polygon. Only outward facing lines cast shadows.
Setting up shadows
------------------
To illustrate the difference, here is an image of a :ref:`LightOccluder2D <class_LightOccluder2D>` with ``Closed``
set to ``off`` in the corresponding :ref:`OccluderPolygon2D <class_OccluderPolygon2D>`, so that the
lines of the polygon can be seen:
After enabling the **Shadow > Enabled** property on a PointLight2D or
DirectionalLight2D node, you will not see any visual difference initially. This
is because no nodes in your scene have any *occluders* yet, which are used as a
basis for shadow casting.
.. image:: img/light_shadow_cull_disabled.png
For shadows to appear in the scene, LightOccluder2D nodes must be added to the
scene. These nodes must also have occluder polygons that are designed to match
the sprite's outline.
.. note:: ``Cull Mode`` is set to ``Disabled``. All three lines cast shadows.
Along with their polygon resource (which must be set to have any visual effect),
LightOccluder2D nodes have 2 properties:
.. image:: img/light_shadow_cull_clockwise.png
- **SDF Collision:** If enabled, the occluder will be part of a real-time
generated *signed distance field* that can be used in custom shaders. When not
using custom shaders that read from this SDF, enabling this makes no visual
difference and has no performance cost, so this is enabled by default for
convenience.
- **Occluder Light Mask:** This is used in tandem with PointLight2D and
DirectionalLight2D's **Shadow > Item Cull Mask** property to control which
objects cast shadows for each light. This can be used to prevent specific
objects from casting shadows.
.. note:: ``Cull Mode`` is set to ``Clockwise``. Only the top and right lines cast shadows.
There are two ways to create light occluders:
.. image:: img/light_shadow_cull_counter_clockwise.png
Automatically generating a light occluder
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. note:: ``Cull Mode`` is set to ``Counter-Clockwise``. Only the bottom line casts a shadow.
If ``Closed`` was set to ``on`` there would be an additional vertical line on the
left which would cast a shadow as well.
Occluders can be created automatically from Sprite2D nodes by selecting the
node, clicking the **Sprite2D** menu at the top of the 2D editor then choosing
**Create LightOccluder2D Sibling**.
When you have added the :ref:`LightOccluder2Ds <class_LightOccluder2D>` the shadows still won't
appear. You need to go back into the :ref:`PointLight2Ds <class_PointLight2D>` and under the Shadow
section set ``Enable`` to ``on``. This turns on shadows with hard edges like in the image below.
In the dialog that appears, an outline will surround your sprite's edges. If the
outline matches the sprite's edges closely, you can click **OK**. If the outline
is too far away from the sprite's edges (or is "eating" into the sprite's
edges), adjust **Grow (pixels)** and **Shrink (pixels)**, then click **Update
Preview**. Repeat this operation until you get satisfactory results.
.. image:: img/light_shadow_filter0_pcf0.png
Manually drawing a light occluder
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To give the shadows that nice, soft edge look we set the variables ``filter``, ``filter smooth``, and
``gradient length``. Godot supports `Percentage Closer Filtering <https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch11.html>`_
(PCF), which takes multiple samples of the shadow map around a pixel and blurs them to create
a smooth shadow effect. The higher the number of samples the smoother the shadow will
look, but the slower it will run. That is why Godot provides 3-13 samples by default and allows you to choose.
The demo uses PCF7.
Create a LightOccluder2D node, then select the node and click the "+" button at
the top top of the 2D editor. When asked to create a polygon resource, answer
**Yes**. You can then start drawing an occluder polygon by clicking to create
new points. You can remove existing points by right-clicking them, and you can
create new points from the existing line by clicking on the line then dragging.
.. image:: img/light_shadow_normal.png
The following properties can be adjusted on 2D lights that have shadows enabled:
.. note:: This is a shadow rendered with the demo's settings. ``gradient length`` is set
to ``1.3``, ``filter smooth`` is set to ``11.1``, and ``filter`` is set to ``PCF7``.
- **Color:** The color of shaded areas. By default, shaded areas are fully
black, but this can be changed for artistic purposes. The color's alpha
channel controls how much the shadow is tinted by the specified color.
- **Filter:** The filter mode to use for shadows. The default **None** is the
fastest to render, and is well suited for games with a pixel art aesthetic
(due to its "blocky" visuals). If you want a soft shadow, use **PCF5**
instead. **PCF13** is even softer, but is the most demanding to render. PCF13
should only be used for a few lights at once due to its high rendering cost.
- **Filter Smooth:** Controls how much softening is applied to shadows when
**Filter** is set to **PCF5** or **PCF13**. Higher values result in a softer
shadow, but may cause banding artifacts to be visible (especially with PCF5).
- **Item Cull Mask:** Controls which LightOccluder2D nodes cast shadows,
depending on their respective **Occluder Light Mask** properties.
.. image:: img/light_shadow_pcf13.png
.. figure:: img/2d_lights_and_shadows_hard_shadow.webp
:align: center
:alt: Hard shadows
.. note:: ``filter`` is set to ``PCF13``. Notice how the shadow becomes wider, this is because the
distance between samples is based on the variable ``filter smooth``.
Hard shadows
In order to make use of filtering you need to set the ``filter smooth`` variable.
This dictates how far apart the samples are. If you want the soft area to extend quite far, you can increase
the size of ``filter smooth``. However, with few samples and a large filter smooth, you can see lines
forming between the samples.
.. figure:: img/2d_lights_and_shadows_soft_shadow.webp
:align: center
:alt: Soft shadows (PCF13, Filter Smooth 1.5)
.. image:: img/light_shadow_filter30.png
Soft shadows (PCF13, Filter Smooth 1.5)
.. note:: ``filter smooth`` is set to ``30``.
.. figure:: img/2d_lights_and_shadows_soft_shadow_streaks.webp
:align: center
:alt: Soft shadows with streaking artifacts due to Filter Smooth being too high (PCF5, Filter Smooth 4)
The different :ref:`Light <class_Light2D>` nodes in the demo use different values for filter smooth.
Play around with it and see what you like.
Soft shadows with streaking artifacts due to Filter Smooth being too high (PCF5, Filter Smooth 4)
.. image:: img/light_shadow_filter0.png
Occluder draw order
^^^^^^^^^^^^^^^^^^^
.. note:: ``filter smooth`` is set to ``0``.
**LightOccluder2Ds follows the usual 2D drawing order.** This is important for 2D
lighting, as this is how you control whether the occluder should occlude the
sprite itself or not.
Lastly, there is the variable ``gradient length``. For some smooth shadows it is preferable not to have the
shadow start immediately on the object, as this produces a hard edge. The gradient length variable creates
a smooth gradient to begin the shadow to reduce the effect of the hard edge.
If the LightOccluder2D node is a *sibling* of the sprite, the occluder will
occlude the sprite itself if it's placed *below* the sprite in the scene tree.
.. image:: img/light_shadow_grad0.png
If the LightOccluder2D node is a *child* of the sprite, the occluder will
occlude the sprite itself if **Show Behind Parent** is disabled on the
LightOccluder2D node (which is the default).
.. note:: ``gradient length`` is set to ``0``.
Normal and specular maps
------------------------
.. image:: img/light_shadow_grad10.png
Normal maps and specular maps can greatly enhance the sense of depth of your 2D
lighting. Similar to how these work in 3D rendering, normal maps can help make
lighting look less flat by varying its intensity depending on the direction of
the surface receiving light (on a per-pixel basis). Specular maps further help
improve visuals by making some of the light reflect back to the viewer.
.. note:: ``gradient length`` is set to ``10``.
Both PointLight2D and DirectionalLight2D support normal mapping and specular
mapping. Since Godot 4.0, normal and specular maps can be assigned to any 2D
element, including nodes that inherit from Node2D or Control.
You will need to play around with the options a bit to find settings that suit your project. There is no right solution
for everyone, which is why Godot provides so much flexibility. Just keep in mind that the higher ``filter``
set the more expensive the shadows will be.
A normal map represents the direction in which each pixel is "pointing" towards.
This information is then used by the engine to correctly apply lighting to 2D
surfaces in a physically plausible way. Normal maps are typically created from
hand-painted height maps, but they can also be automatically generated from
other textures.
A specular map defines how much each pixel should reflect light (and in which
color, if the specular map contains color). Brighter values will result in a
brighter reflection at that given spot on the texture. Specular maps are
typically created with manual editing, using the diffuse texture as a base.
.. tip::
If you don't have normal or specular maps for your sprites, you can generate
them using the free and open source `Laigter <https://azagaya.itch.io/laigter>`__
tool.
To set up normal maps and/or specular maps on a 2D node, create a new
CanvasTexture resource for the property that draws the node's texture. For
example, on a Sprite2D:
.. figure:: img/2d_lights_and_shadows_create_canvastexture.webp
:align: center
:alt: Creating a CanvasTexture resource for a Sprite2D node
Creating a CanvasTexture resource for a Sprite2D node
Expand the newly created resource. You can find several properties you will need
to adjust:
- **Diffuse > Texture:** The base color texture. In this property, load the
texture you're using for the sprite itself.
- **Normal Map > Texture:** The normal map texture. In this property, load a
normal map texture you've generated from a height map (see the tip above).
- **Specular > Texture:** The specular map texture, which controls the specular
intensity of each pixel on the diffuse texture. The specular map is usually
grayscale, but it can also contain color to multiply the color of reflections
accordingly. In this property, load a specular map texture you've created (see
the tip above).
- **Specular > Color:** The color multiplier for specular reflections.
- **Specular > Shininess:** The specular exponent to use for reflections. Lower
values will increase the brightness of reflections and make them more diffuse,
while higher values will make reflections more localized. High values are more
suited for wet-looking surfaces.
- **Texture > Filter:** Can be set to override the texture filtering mode,
regardless of what the node's property is set to (or the
**Rendering > Textures > Canvas Textures > Default Texture Filter** project
setting).
- **Texture > Repeat:** Can be set to override the texture filtering mode,
regardless of what the node's property is set to (or the
**Rendering > Textures > Canvas Textures > Default Texture Repeat** project
setting).
After enabling normal mapping, you may notice that your lights appear to be
weaker. To resolve this, increase the **Height** property on your PointLight2D
and DirectionalLight2D nodes. You may also want to increase the lights's
**Energy** property slightly to get closer to how your lighting's intensity
looked prior to enabling normal mapping.
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB