2d_parallax.rst 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. .. _doc_2d_parallax:
  2. 2D Parallax
  3. ===========
  4. Introduction
  5. ------------
  6. Parallax is an effect used to simulate depth by having textures move at different speeds relative to the camera. Godot
  7. provides the :ref:`Parallax2D<class_parallax2d>` node to achieve this effect. It can still be easy to get tripped
  8. up though, so this page provides in-depth descriptions of some properties and how to fix some common mistakes.
  9. .. note::
  10. This page covers how to use :ref:`Parallax2D<class_parallax2d>`, which is
  11. recommended to use over the :ref:`ParallaxLayer<class_parallaxlayer>` and
  12. :ref:`ParallaxBackground<class_parallaxbackground>` nodes.
  13. Getting started
  14. ---------------
  15. The parallax node supports adding nodes that render things as children, so you can use one or many nodes to make up each
  16. layer. To begin, place each node or nodes you want to have scroll independently as a child of their own parallax node.
  17. Make sure that the top left of the textures used are at the ``(0, 0)`` crossing, like in the image below. See the section
  18. on :ref:`positioning <doc_2d_parallax_positioning>` for why this is important.
  19. .. image:: img/2d_parallax_size_viewport.webp
  20. The scene above uses one prepared texture for the higher clouds in a :ref:`Sprite2D <class_sprite2d>`, but you could
  21. just as easily use multiple nodes spaced out to compose the layer.
  22. Scroll scale
  23. ------------
  24. The backbone of the parallax effect is the :ref:`scroll_scale <class_parallax2d_property_scroll_scale>` property.
  25. It works as a scroll-speed multiplier, allowing layers to move at a different speed than the camera for each axis set.
  26. A value of 1 makes the parallax node scroll at the same speed as the camera. If you want your image to look further away
  27. when scrolling, use a value lower than 1, with 0 bringing it to a complete stop. If you want something to appear closer
  28. to the camera, use a value higher than 1, making it scroll faster.
  29. The scene above is comprised of five layers. Some good :ref:`scroll_scale <class_parallax2d_property_scroll_scale>`
  30. values might be:
  31. - ``(0.7, 1)`` - Forest
  32. - ``(0.5, 1)`` - Hills
  33. - ``(0.3, 1)`` - Lower Clouds
  34. - ``(0.2, 1)`` - Higher Clouds
  35. - ``(0.1, 1)`` - Sky
  36. The video below displays how these values affect scrolling while in-game:
  37. .. video:: video/2d_parallax_scroll_scale.webm
  38. :alt: A scene with five layers scrolling at different speeds
  39. :autoplay:
  40. :loop:
  41. :muted:
  42. :align: default
  43. Infinite repeat
  44. ---------------
  45. :ref:`Parallax2D<class_parallax2d>` provides a bonus effect that gives textures the illusion of repeating infinitely.
  46. :ref:`repeat_size<class_parallax2d_property_repeat_size>` tells the node to snap its position forward or back when the
  47. camera scrolls by the set value. This effect is achieved by adding a single repeat to all the child canvas items offset
  48. by the value. While the camera scrolls between the image and its repeat, it invisibly snaps back giving the appearance
  49. of a looping image.
  50. .. image:: img/2d_parallax_scroll.gif
  51. Being a delicate effect, it's easy for unfamiliar users to make mistakes with their setup. Let's go over the "how" and
  52. "why" of a few common problems users encounter.
  53. Poor sizing
  54. ~~~~~~~~~~~
  55. The infinite repeat effect is easiest to work with when you have an image designed to repeat seamlessly and is the same
  56. size or larger than your viewport **before** setting the :ref:`repeat_size<class_parallax2d_property_repeat_size>`. If
  57. you aren't able to obtain assets that are designed for this task, there are some other things you can do to better
  58. prepare your image in regards to size.
  59. Here is an example of a texture that is too small for its viewport:
  60. .. image:: img/2d_parallax_size_bad.webp
  61. We can see that the viewport size is 500x300 but the texture is 288x208. If we set the
  62. :ref:`repeat_size<class_parallax2d_property_repeat_size>` to the size of our image, the infinite repeat effect doesn't
  63. scroll properly because the original texture doesn't cover the viewport. If we set the
  64. :ref:`repeat_size<class_parallax2d_property_repeat_size>` to the size of the viewport, we have a large gap. What can we
  65. do?
  66. Make the viewport smaller
  67. ^^^^^^^^^^^^^^^^^^^^^^^^^
  68. The simplest answer is to make the viewport the same size or smaller than your textures.
  69. In **Project Settings > Display > Window**, change the
  70. :ref:`Viewport Width<class_ProjectSettings_property_display/window/size/viewport_width>`
  71. and :ref:`Viewport Height<class_ProjectSettings_property_display/window/size/viewport_height>`
  72. settings to match your background.
  73. .. image:: img/2d_parallax_size_viewport.webp
  74. Scale the Parallax2D
  75. ^^^^^^^^^^^^^^^^^^^^
  76. If you're not aiming for a pixel-perfect style, or don't mind a little blurriness, you may opt to scale the textures
  77. larger to fit your screen. Set the :ref:`scale<class_node2d_property_scale>` of the :ref:`Parallax2D<class_parallax2d>`,
  78. and all child textures scale with it.
  79. Scale the child nodes
  80. ^^^^^^^^^^^^^^^^^^^^^
  81. Similar to scaling the :ref:`Parallax2D<class_parallax2d>`, you can scale your :ref:`Sprite2D<class_sprite2d>` nodes to
  82. be large enough to cover the screen. Keep in mind that some settings like
  83. :ref:`Parallax2D.repeat_size<class_parallax2d_property_repeat_size>` and
  84. :ref:`Sprite2D.region_rect<class_sprite2d_property_region_rect>` do not take scaling into account, so it's necessary to
  85. adjust these values based on the scale.
  86. .. image:: img/2d_parallax_size_scale.webp
  87. Repeat the textures
  88. ^^^^^^^^^^^^^^^^^^^
  89. You can also start off on the right foot by preparing child nodes earlier in the process. If you have a
  90. :ref:`Sprite2D<class_sprite2d>` you'd like to repeat, but is too small, you can do the following to repeat it:
  91. - set :ref:`texture_repeat<class_canvasitem_property_texture_repeat>` to :ref:`CanvasItem.TEXTURE_REPEAT_ENABLED<class_canvasitem_constant_TEXTURE_REPEAT_ENABLED>`
  92. - set :ref:`region_enabled<class_sprite2d_property_region_enabled>` to ``true``
  93. - set the :ref:`region_rect<class_sprite2d_property_region_rect>` to a multiple of the size of your texture large enough to cover the viewport.
  94. Below, you can see that repeating the image twice makes it large enough to cover the screen.
  95. .. image:: img/2d_parallax_size_repeat.webp
  96. .. _doc_2d_parallax_positioning:
  97. Poor positioning
  98. ~~~~~~~~~~~~~~~~
  99. It's common to see users mistakenly set all of their textures to be centered at ``(0,0)``:
  100. .. image:: img/2d_parallax_single_centered.webp
  101. This creates problems with the infinite repeat effect and should be avoided. The "infinite repeat canvas" starts at
  102. ``(0,0)`` and expands down and to the right to the size of the :ref:`repeat_size<class_parallax2d_property_repeat_size>`
  103. value.
  104. .. image:: img/2d_parallax_single_expand.webp
  105. If the textures are centered on the ``(0,0)`` crossing, the infinite repeat canvas is only partly covered, so it
  106. only partly repeats.
  107. Would increasing ``repeat_times`` fix this?
  108. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  109. Increasing :ref:`repeat_times<class_parallax2d_property_repeat_times>` technically *would* work in some scenarios, but
  110. is a brute force solution and not the problem it is designed to solve (we'll go over this in a bit). A better fix is to
  111. understand how the repeat effect works and set up the parallax textures appropriately to begin with.
  112. First, check to see if any textures are spilling over onto the negative parts of the canvas. Make sure the textures
  113. used in the parallax nodes fit inside the "infinite repeat canvas" starting at ``(0,0)``. That way, if
  114. :ref:`Parallax2D.repeat_size<class_parallax2d_property_repeat_size>` is set correctly, it should look something like
  115. this, with one single loop of the image the same size or larger than the viewport:
  116. .. image:: img/2d_parallax_repeat_good_norect.webp
  117. If you think of how the image scrolls across the screen, it starts by displaying what's inside the red rectangle
  118. (determined by :ref:`repeat_size<class_parallax2d_property_repeat_size>`), and when it reaches what's inside the yellow
  119. rectangle it zips the image forward to give the illusion of scrolling forever.
  120. .. image:: img/2d_parallax_repeat_good.webp
  121. If you have the image positioned away from the "infinite repeat canvas", when the camera reaches the yellow rectangle,
  122. half of the image is cut off before it jumps forward like in the image below:
  123. .. image:: img/2d_parallax_repeat_bad.webp
  124. Scroll offset
  125. -------------
  126. If your parallax textures are already working correctly, but you prefer it to start at a different point,
  127. :ref:`Parallax2D<class_parallax2d>` comes with a :ref:`scroll_offset<class_parallax2d_property_scroll_offset>` property
  128. used to offset where the infinite repeat canvas starts. As an example, if your image is 288x208, setting
  129. the :ref:`scroll_offset<class_parallax2d_property_scroll_offset>` to ``(-144,0)`` or ``(144,0)`` allows it to begin
  130. halfway across the image.
  131. Repeat times
  132. ------------
  133. Ideally, following this guide, your parallax textures are large enough to cover the screen even when zoomed out.
  134. Until now, we have had a perfectly fitting 288x208 texture inside of a 288x208 viewport. However, problems
  135. occur when we zoom out by setting the :ref:`Camera2D.zoom<class_camera2d_property_zoom>` to ``(0.5, 0.5)``:
  136. .. image:: img/2d_parallax_zoom_single.webp
  137. Even though everything is correctly set for the viewport at the default zoom level, zooming out makes it smaller than
  138. the viewport, breaking the infinite repeat effect. This is where
  139. :ref:`repeat_times<class_parallax2d_property_repeat_times>` can help out. Setting a value of ``3`` (one extra
  140. repeat behind and in front), it is now large enough to accommodate the infinite repeat effect.
  141. .. image:: img/2d_parallax_zoom_repeat_times.webp
  142. If these textures were meant to be repeated vertically, we would have specified a ``y`` value for the
  143. :ref:`repeat_size<class_parallax2d_property_repeat_size>`. The
  144. :ref:`repeat_times<class_parallax2d_property_repeat_times>` would automatically add a repeat above and below as well.
  145. This is only a horizontal parallax, so it leaves an empty block above and below the image. How do we solve this? We
  146. need to get creative! In this example, we stretch the sky higher, and grass sprite lower. The textures now support the
  147. normal zoom level and zooming out to half size.
  148. .. image:: img/2d_parallax_zoom_repeat_adjusted.webp
  149. Split screen
  150. ------------
  151. Most tutorials for making a split screen game in Godot begin by writing a small script to assign
  152. the :ref:`Viewport.world_2d<class_viewport_property_world_2d>` of the first SubViewport to the second, so they have a
  153. shared display. Questions often pop up about how to share a parallax effect between both screens.
  154. The parallax effect fakes a perspective by moving the positions of different textures in relation to the camera. This is
  155. understandably problematic if you have multiple cameras, because your textures can't be in two places at once!
  156. This is still achievable by cloning the parallax nodes into the second (or third or fourth)
  157. :ref:`SubViewport<class_subviewport>`. Here's how a setup looks for a two player game:
  158. .. image:: img/2d_parallax_splitscreen.webp
  159. Of course, now both backgrounds show in both SubViewports. What we want is for each parallax to only show in their
  160. corresponding viewport. We can achieve this by doing the following:
  161. - Leave all parallax nodes at their default :ref:`visibility_layer<class_canvasitem_property_visibility_layer>` of 1.
  162. - Set the first SubViewport's :ref:`canvas_cull_mask<class_viewport_property_canvas_cull_mask>` to only layers 1 and 2.
  163. - Do the same for the second SubViewport but use layers 1 and 3.
  164. - Give your parallax nodes in the first SubViewport a common parent and set its :ref:`visibility_layer<class_canvasitem_property_visibility_layer>` to 2.
  165. - Do the same for the second SubViewport's parallax nodes, but use a layer of 3.
  166. How does this work? If a canvas item has a :ref:`visibility_layer<class_canvasitem_property_visibility_layer>` that
  167. doesn't match the SubViewport's :ref:`canvas_cull_mask<class_viewport_property_canvas_cull_mask>`, it will hide all
  168. children, even if they do. We use this to our advantage, letting the SubViewports cut off rendering of parallax nodes
  169. whose parent doesn't have a supported :ref:`visibility_layer<class_canvasitem_property_visibility_layer>`.
  170. Previewing in the editor
  171. ------------------------
  172. Prior to 4.3, the recommendation was to place every layer in their own
  173. :ref:`ParallaxBackground<class_parallaxbackground>`, enable the
  174. :ref:`follow_viewport_enabled<class_canvaslayer_property_follow_viewport_enabled>` property, and scale the individual
  175. layer. This method has always been tricky to get right, but is still achievable by using a
  176. :ref:`CanvasLayer<class_canvaslayer>` instead of a :ref:`ParallaxBackground<class_parallaxbackground>`.
  177. .. note::
  178. Another recommendation is `KoBeWi's "Parallax2D Preview" addon <https://github.com/KoBeWi/Godot-Parallax2D-Preview>`_.
  179. It provides a few different preview modes and is very handy!