2d_lights_and_shadows.rst 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. .. _doc_2d_lights_and_shadows:
  2. 2D lights and shadows
  3. =====================
  4. Introduction
  5. ------------
  6. By default, 2D scenes in Godot are unshaded, with no lights and shadows visible.
  7. While this is fast to render, unshaded scenes can look bland. Godot provides the
  8. ability to use real-time 2D lighting and shadows, which can greatly enhance the
  9. sense of depth in your project.
  10. .. figure:: img/2d_lights_and_shadows_disabled.webp
  11. :align: center
  12. :alt: No 2D lights or shadows, scene is unshaded
  13. No 2D lights or shadows, scene is unshaded
  14. .. figure:: img/2d_lights_and_shadows_enabled_no_shadows.webp
  15. :align: center
  16. :alt: 2D lights enabled (without shadows)
  17. 2D lights enabled (without shadows)
  18. .. figure:: img/2d_lights_and_shadows_enabled.webp
  19. :align: center
  20. :alt: 2D lights and shadows enabled
  21. 2D lights and shadows enabled
  22. Nodes
  23. -----
  24. There are several nodes involved in a complete 2D lighting setup:
  25. - :ref:`CanvasModulate <class_CanvasModulate>` (to darken the rest of the scene)
  26. - :ref:`PointLight2D <class_PointLight2D>` (for omnidirectional or spot lights)
  27. - :ref:`DirectionalLight2D <class_DirectionalLight2D>` (for sunlight or moonlight)
  28. - :ref:`LightOccluder2D <class_LightOccluder2D>` (for light shadow casters)
  29. - Other 2D nodes that receive lighting, such as Sprite2D or TileMapLayer.
  30. :ref:`CanvasModulate <class_CanvasModulate>` is used to darken the scene by
  31. specifying a color that will act as the base "ambient" color. This is the final
  32. lighting color in areas that are *not* reached by any 2D light. Without a
  33. CanvasModulate node, the final scene would look too bright as 2D lights would
  34. only brighten the existing unshaded appearance (which appears fully lit).
  35. :ref:`Sprite2Ds <class_Sprite2D>` are used to display the textures for the light
  36. blobs, the background, and for the shadow casters.
  37. :ref:`PointLight2Ds <class_PointLight2D>` are used to light the scene. The way a
  38. light typically works is by adding a selected texture over the rest of the scene
  39. to simulate lighting.
  40. :ref:`LightOccluder2Ds <class_LightOccluder2D>` are used to tell the shader
  41. which parts of the scene cast shadows. These occluders can be placed as
  42. independent nodes or can be part of a TileMapLayer node.
  43. The shadows appear only on areas covered by the :ref:`PointLight2D
  44. <class_PointLight2D>` and their direction is based on the center of the
  45. :ref:`Light <class_PointLight2D>`.
  46. .. note::
  47. The background color does **not** receive any lighting. If you want light to
  48. be cast on the background, you need to add a visual representation for the
  49. background, such as a Sprite2D.
  50. The Sprite2D's **Region** properties can be helpful to quickly create a
  51. repeating background texture, but remember to also set **Texture > Repeat** to
  52. **Enabled** in the Sprite2D's properties.
  53. Point lights
  54. ------------
  55. Point lights (also called positional lights) are the most common element in 2D
  56. lighting. Point lights can be used to represent light from torches, fire,
  57. projectiles, etc.
  58. PointLight2D offers the following properties to tweak in the inspector:
  59. - **Texture:** The texture to use as a light source. The texture's size
  60. determines the size of the light. The texture may have an alpha channel, which
  61. is useful when using Light2D's **Mix** blend mode, but it is not required if
  62. using the **Add** (default) or **Subtract** blend modes.
  63. - **Offset:** The offset for the light texture. Unlike when you move the light
  64. node, changing the offset does *not* cause shadows to move.
  65. - **Texture Scale:** The multiplier for the light's size. Higher values will
  66. make the light extend out further. Larger lights have a higher performance
  67. cost as they affect more pixels on screen, so consider this before increasing
  68. a light's size.
  69. - **Height:** The light's virtual height with regards to normal mapping. By
  70. default, the light is very close to surfaces receiving lights. This will make
  71. lighting hardly visible if normal mapping is used, so consider increasing this
  72. value. Adjusting the light's height only makes a visible difference on
  73. surfaces that use normal mapping.
  74. If you don't have a pre-made texture to use in a light, you can use this "neutral"
  75. point light texture (right-click > **Save Image As…**):
  76. .. figure:: img/2d_lights_and_shadows_neutral_point_light.webp
  77. :align: center
  78. :alt: Neutral point light texture
  79. Neutral point light texture
  80. If you need different falloff, you can procedurally create a texture by assigning
  81. a **New GradientTexture2D** on the light's **Texture** property. After creating
  82. the resource, expand its **Fill** section and set the fill mode to **Radial**.
  83. You will then have to adjust the gradient itself to start from opaque white to
  84. transparent white, and move its starting location to be in the center.
  85. Directional light
  86. -----------------
  87. New in Godot 4.0 is the ability to have directional lighting in 2D. Directional
  88. lighting is used to represent sunlight or moonlight. Light rays are casted
  89. parallel to each other, as if the sun or moon was infinitely far away from the
  90. surface that is receiving the light.
  91. DirectionalLight2D offers the following properties:
  92. - **Height:** The light's virtual height with regards to normal mapping (``0.0``
  93. = parallel to surfaces, ``1.0`` = perpendicular to surfaces). By default, the
  94. light is fully parallel with the surfaces receiving lights. This will make
  95. lighting hardly visible if normal mapping is used, so consider increasing this
  96. value. Adjusting the light's height only makes a visual difference on surfaces
  97. that use normal mapping. **Height** does not affect shadows' appearance.
  98. - **Max Distance:** The maximum distance from the camera center objects can be
  99. before their shadows are culled (in pixels). Decreasing this value can prevent
  100. objects located outside the camera from casting shadows (while also improving
  101. performance). Camera2D zoom is not taken into account by **Max Distance**,
  102. which means that at higher zoom values, shadows will appear to fade out sooner
  103. when zooming onto a given point.
  104. .. note::
  105. Directional shadows will always appear to be infinitely long, regardless
  106. of the value of the **Height** property. This is a limitation of the shadow
  107. rendering method used for 2D lights in Godot.
  108. To have directional shadows that are not infinitely long, you should disable
  109. shadows in the DirectionalLight2D and use a custom shader that reads from
  110. the 2D signed distance field instead. This distance field is automatically
  111. generated from LightOccluder2D nodes present in the scene.
  112. Common light properties
  113. -----------------------
  114. Both PointLight2D and DirectionalLight2D offer common properties, which are part
  115. of the Light2D base class:
  116. - **Enabled:** Allows toggling the light's visibility. Unlike hiding the light
  117. node, disabling this property will not hide the light's children.
  118. - **Editor Only:** If enabled, the light is only visible within the editor. It
  119. will be automatically disabled in the running project.
  120. - **Color:** The light's color.
  121. - **Energy:** The light's intensity multiplier. Higher values result in a brighter light.
  122. - **Blend Mode:** The blending formula used for light computations. The default
  123. **Add** is suited for most use cases. **Subtract** can be used for negative
  124. lights, which are not physically accurate but can be used for special effects.
  125. The **Mix** blend mode mixes the value of pixels corresponding to the light's
  126. texture with the values of pixels under it by linear interpolation.
  127. - **Range > Z Min:** The lowest Z index affected by the light.
  128. - **Range > Z Max:** The highest Z index affected by the light.
  129. - **Range > Layer Min:** The lowest visual layer affected by the light.
  130. - **Range > Layer Max:** The highest visual layer affected by the light.
  131. - **Range > Item Cull Mask:** Controls which nodes receive light from this node,
  132. depending on the other nodes' enabled visual layers **Occluder Light Mask**.
  133. This can be used to prevent certain objects from receiving light.
  134. .. _doc_2d_lights_and_shadows_setting_up_shadows:
  135. Setting up shadows
  136. ------------------
  137. After enabling the **Shadow > Enabled** property on a PointLight2D or
  138. DirectionalLight2D node, you will not see any visual difference initially. This
  139. is because no nodes in your scene have any *occluders* yet, which are used as a
  140. basis for shadow casting.
  141. For shadows to appear in the scene, LightOccluder2D nodes must be added to the
  142. scene. These nodes must also have occluder polygons that are designed to match
  143. the sprite's outline.
  144. Along with their polygon resource (which must be set to have any visual effect),
  145. LightOccluder2D nodes have 2 properties:
  146. - **SDF Collision:** If enabled, the occluder will be part of a real-time
  147. generated *signed distance field* that can be used in custom shaders. When not
  148. using custom shaders that read from this SDF, enabling this makes no visual
  149. difference and has no performance cost, so this is enabled by default for
  150. convenience.
  151. - **Occluder Light Mask:** This is used in tandem with PointLight2D and
  152. DirectionalLight2D's **Shadow > Item Cull Mask** property to control which
  153. objects cast shadows for each light. This can be used to prevent specific
  154. objects from casting shadows.
  155. There are two ways to create light occluders:
  156. Automatically generating a light occluder
  157. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  158. Occluders can be created automatically from Sprite2D nodes by selecting the
  159. node, clicking the **Sprite2D** menu at the top of the 2D editor then choosing
  160. **Create LightOccluder2D Sibling**.
  161. In the dialog that appears, an outline will surround your sprite's edges. If the
  162. outline matches the sprite's edges closely, you can click **OK**. If the outline
  163. is too far away from the sprite's edges (or is "eating" into the sprite's
  164. edges), adjust **Grow (pixels)** and **Shrink (pixels)**, then click **Update
  165. Preview**. Repeat this operation until you get satisfactory results.
  166. Manually drawing a light occluder
  167. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  168. Create a LightOccluder2D node, then select the node and click the "+" button at
  169. the top of the 2D editor. When asked to create a polygon resource, answer
  170. **Yes**. You can then start drawing an occluder polygon by clicking to create
  171. new points. You can remove existing points by right-clicking them, and you can
  172. create new points from the existing line by clicking on the line then dragging.
  173. The following properties can be adjusted on 2D lights that have shadows enabled:
  174. - **Color:** The color of shaded areas. By default, shaded areas are fully
  175. black, but this can be changed for artistic purposes. The color's alpha
  176. channel controls how much the shadow is tinted by the specified color.
  177. - **Filter:** The filter mode to use for shadows. The default **None** is the
  178. fastest to render, and is well suited for games with a pixel art aesthetic
  179. (due to its "blocky" visuals). If you want a soft shadow, use **PCF5**
  180. instead. **PCF13** is even softer, but is the most demanding to render. PCF13
  181. should only be used for a few lights at once due to its high rendering cost.
  182. - **Filter Smooth:** Controls how much softening is applied to shadows when
  183. **Filter** is set to **PCF5** or **PCF13**. Higher values result in a softer
  184. shadow, but may cause banding artifacts to be visible (especially with PCF5).
  185. - **Item Cull Mask:** Controls which LightOccluder2D nodes cast shadows,
  186. depending on their respective **Occluder Light Mask** properties.
  187. .. figure:: img/2d_lights_and_shadows_hard_shadow.webp
  188. :align: center
  189. :alt: Hard shadows
  190. Hard shadows
  191. .. figure:: img/2d_lights_and_shadows_soft_shadow.webp
  192. :align: center
  193. :alt: Soft shadows (PCF13, Filter Smooth 1.5)
  194. Soft shadows (PCF13, Filter Smooth 1.5)
  195. .. figure:: img/2d_lights_and_shadows_soft_shadow_streaks.webp
  196. :align: center
  197. :alt: Soft shadows with streaking artifacts due to Filter Smooth being too high (PCF5, Filter Smooth 4)
  198. Soft shadows with streaking artifacts due to Filter Smooth being too high (PCF5, Filter Smooth 4)
  199. Occluder draw order
  200. ^^^^^^^^^^^^^^^^^^^
  201. **LightOccluder2Ds follows the usual 2D drawing order.** This is important for 2D
  202. lighting, as this is how you control whether the occluder should occlude the
  203. sprite itself or not.
  204. If the LightOccluder2D node is a *sibling* of the sprite, the occluder will
  205. occlude the sprite itself if it's placed *below* the sprite in the scene tree.
  206. If the LightOccluder2D node is a *child* of the sprite, the occluder will
  207. occlude the sprite itself if **Show Behind Parent** is disabled on the
  208. LightOccluder2D node (which is the default).
  209. Normal and specular maps
  210. ------------------------
  211. Normal maps and specular maps can greatly enhance the sense of depth of your 2D
  212. lighting. Similar to how these work in 3D rendering, normal maps can help make
  213. lighting look less flat by varying its intensity depending on the direction of
  214. the surface receiving light (on a per-pixel basis). Specular maps further help
  215. improve visuals by making some of the light reflect back to the viewer.
  216. Both PointLight2D and DirectionalLight2D support normal mapping and specular
  217. mapping. Since Godot 4.0, normal and specular maps can be assigned to any 2D
  218. element, including nodes that inherit from Node2D or Control.
  219. A normal map represents the direction in which each pixel is "pointing" towards.
  220. This information is then used by the engine to correctly apply lighting to 2D
  221. surfaces in a physically plausible way. Normal maps are typically created from
  222. hand-painted height maps, but they can also be automatically generated from
  223. other textures.
  224. A specular map defines how much each pixel should reflect light (and in which
  225. color, if the specular map contains color). Brighter values will result in a
  226. brighter reflection at that given spot on the texture. Specular maps are
  227. typically created with manual editing, using the diffuse texture as a base.
  228. .. tip::
  229. If you don't have normal or specular maps for your sprites, you can generate
  230. them using the free and open source `Laigter <https://azagaya.itch.io/laigter>`__
  231. tool.
  232. To set up normal maps and/or specular maps on a 2D node, create a new
  233. CanvasTexture resource for the property that draws the node's texture. For
  234. example, on a Sprite2D:
  235. .. figure:: img/2d_lights_and_shadows_create_canvastexture.webp
  236. :align: center
  237. :alt: Creating a CanvasTexture resource for a Sprite2D node
  238. Creating a CanvasTexture resource for a Sprite2D node
  239. Expand the newly created resource. You can find several properties you will need
  240. to adjust:
  241. - **Diffuse > Texture:** The base color texture. In this property, load the
  242. texture you're using for the sprite itself.
  243. - **Normal Map > Texture:** The normal map texture. In this property, load a
  244. normal map texture you've generated from a height map (see the tip above).
  245. - **Specular > Texture:** The specular map texture, which controls the specular
  246. intensity of each pixel on the diffuse texture. The specular map is usually
  247. grayscale, but it can also contain color to multiply the color of reflections
  248. accordingly. In this property, load a specular map texture you've created (see
  249. the tip above).
  250. - **Specular > Color:** The color multiplier for specular reflections.
  251. - **Specular > Shininess:** The specular exponent to use for reflections. Lower
  252. values will increase the brightness of reflections and make them more diffuse,
  253. while higher values will make reflections more localized. High values are more
  254. suited for wet-looking surfaces.
  255. - **Texture > Filter:** Can be set to override the texture filtering mode,
  256. regardless of what the node's property is set to (or the
  257. **Rendering > Textures > Canvas Textures > Default Texture Filter** project
  258. setting).
  259. - **Texture > Repeat:** Can be set to override the texture filtering mode,
  260. regardless of what the node's property is set to (or the
  261. **Rendering > Textures > Canvas Textures > Default Texture Repeat** project
  262. setting).
  263. After enabling normal mapping, you may notice that your lights appear to be
  264. weaker. To resolve this, increase the **Height** property on your PointLight2D
  265. and DirectionalLight2D nodes. You may also want to increase the lights's
  266. **Energy** property slightly to get closer to how your lighting's intensity
  267. looked prior to enabling normal mapping.
  268. Using additive sprites as a faster alternative to 2D lights
  269. -----------------------------------------------------------
  270. If you run into performance issues when using 2D lights, it may be worth
  271. replacing some of them with Sprite2D nodes that use additive blending. This is
  272. particularly suited for short-lived dynamic effects, such as bullets or explosions.
  273. Additive sprites are much faster to render, since they don't need to go through
  274. a separate rendering pipeline. Additionally, it is possible to use this approach
  275. with AnimatedSprite2D (or Sprite2D + AnimationPlayer), which allows for animated
  276. 2D "lights" to be created.
  277. However, additive sprites have a few downsides compared to 2D lights:
  278. - The blending formula is inaccurate compared to "actual" 2D lighting. This is
  279. usually not a problem in sufficiently lit areas, but this prevents additive
  280. sprites from correctly lighting up areas that are fully dark.
  281. - Additive sprites cannot cast shadows, since they are not lights.
  282. - Additive sprites ignore normal and specular maps used on other sprites.
  283. To display a sprite with additive blending, create a Sprite2D node and assign a
  284. texture to it. In the inspector, scroll down to the **CanvasItem > Material**
  285. section, unfold it and click the dropdown next to the **Material** property.
  286. Choose **New CanvasItemMaterial**, click the newly created material to edit it,
  287. then set **Blend Mode** to **Add**.