optimizing_3d_performance.rst 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. .. meta::
  2. :keywords: optimization
  3. .. _doc_optimizing_3d_performance:
  4. Optimizing 3D performance
  5. =========================
  6. Culling
  7. -------
  8. Godot will automatically perform view frustum culling in order to prevent
  9. rendering objects that are outside the viewport. This works well for games that
  10. take place in a small area, however things can quickly become problematic in
  11. larger levels.
  12. Occlusion culling
  13. ^^^^^^^^^^^^^^^^^
  14. Walking around a town for example, you may only be able to see a few buildings
  15. in the street you are in, as well as the sky and a few birds flying overhead. As
  16. far as a naive renderer is concerned however, you can still see the entire town.
  17. It won't just render the buildings in front of you, it will render the street
  18. behind that, with the people on that street, the buildings behind that. You
  19. quickly end up in situations where you are attempting to render 10× or 100× more
  20. than what is visible.
  21. Things aren't quite as bad as they seem, because the Z-buffer usually allows the
  22. GPU to only fully shade the objects that are at the front. This is called *depth
  23. prepass* and is enabled by default in Godot when using the Forward+ or
  24. Compatibility rendering methods. However, unneeded objects are still reducing
  25. performance.
  26. One way we can potentially reduce the amount to be rendered is to **take advantage
  27. of occlusion**. Godot 4.0 and later offers a new approach to occlusion culling
  28. using occluder nodes. See :ref:`doc_occlusion_culling` for instructions on
  29. setting up occlusion culling in your scene.
  30. .. note::
  31. In some cases, you may have to adapt your level design to add more occlusion
  32. opportunities. For example, you may have to add more walls to prevent the player
  33. from seeing too far away, which would decrease performance due to the lost
  34. opportunities for occlusion culling.
  35. Transparent objects
  36. -------------------
  37. Godot sorts objects by :ref:`Material <class_Material>` and :ref:`Shader
  38. <class_Shader>` to improve performance. This, however, can not be done with
  39. transparent objects. Transparent objects are rendered from back to front to make
  40. blending with what is behind work. As a result,
  41. **try to use as few transparent objects as possible**. If an object has a
  42. small section with transparency, try to make that section a separate surface
  43. with its own material.
  44. For more information, see the :ref:`GPU optimizations <doc_gpu_optimization>`
  45. doc.
  46. Level of detail (LOD)
  47. ---------------------
  48. In some situations, particularly at a distance, it can be a good idea to
  49. **replace complex geometry with simpler versions**. The end user will probably
  50. not be able to see much difference. Consider looking at a large number of trees
  51. in the far distance. There are several strategies for replacing models at
  52. varying distance. You could use lower poly models, or use transparency to
  53. simulate more complex geometry.
  54. Godot 4 offers several ways to control level of detail:
  55. - An automatic approach on mesh import using :ref:`doc_mesh_lod`.
  56. - A manual approach configured in the 3D node using :ref:`doc_visibility_ranges`.
  57. - :ref:`Decals <doc_using_decals>` and :ref:`lights <doc_lights_and_shadows>`
  58. can also benefit from level of detail using their respective
  59. **Distance Fade** properties.
  60. While they can be used independently, these approaches are most effective when
  61. used together. For example, you can set up visibility ranges to hide particle
  62. effects that are too far away from the player to notice. At the same time, you
  63. can rely on mesh LOD to make the particle effect's meshes rendered with less
  64. detail at a distance.
  65. Visibility ranges are also a good way to set up *impostors* for distant geometry
  66. (see below).
  67. Billboards and imposters
  68. ^^^^^^^^^^^^^^^^^^^^^^^^
  69. The simplest version of using transparency to deal with LOD is billboards. For
  70. example, you can use a single transparent quad to represent a tree at distance.
  71. This can be very cheap to render, unless of course, there are many trees in
  72. front of each other. In this case, transparency may start eating into fill rate
  73. (for more information on fill rate, see :ref:`doc_gpu_optimization`).
  74. An alternative is to render not just one tree, but a number of trees together as
  75. a group. This can be especially effective if you can see an area but cannot
  76. physically approach it in a game.
  77. You can make imposters by pre-rendering views of an object at different angles.
  78. Or you can even go one step further, and periodically re-render a view of an
  79. object onto a texture to be used as an imposter. At a distance, you need to move
  80. the viewer a considerable distance for the angle of view to change
  81. significantly. This can be complex to get working, but may be worth it depending
  82. on the type of project you are making.
  83. Use instancing (MultiMesh)
  84. ^^^^^^^^^^^^^^^^^^^^^^^^^^
  85. If several identical objects have to be drawn in the same place or nearby, try
  86. using :ref:`MultiMesh <class_MultiMesh>` instead. MultiMesh allows the drawing
  87. of many thousands of objects at very little performance cost, making it ideal
  88. for flocks, grass, particles, and anything else where you have thousands of
  89. identical objects.
  90. See also the :ref:`Using MultiMesh <doc_using_multimesh>` documentation.
  91. Bake lighting
  92. -------------
  93. Lighting objects is one of the most costly rendering operations. Realtime
  94. lighting, shadows (especially multiple lights), and
  95. :ref:`global illumination <doc_introduction_to_global_illumination>` are especially
  96. expensive. They may simply be too much for lower power mobile devices to handle.
  97. **Consider using baked lighting**, especially for mobile. This can look fantastic,
  98. but has the downside that it will not be dynamic. Sometimes, this is a tradeoff
  99. worth making.
  100. See :ref:`doc_using_lightmap_gi` for instructions on using baked lightmaps. For
  101. best performance, you should set lights' bake mode to **Static** as opposed to
  102. the default **Dynamic**, as this will skip real-time lighting on meshes that
  103. have baked lighting.
  104. The downside of lights with the **Static** bake mode is that they can't cast
  105. shadows onto meshes with baked lighting. This can make scenes with outdoor
  106. environments and dynamic objects look flat. A good balance between performance
  107. and quality is to keep **Dynamic** for the :ref:`class_DirectionalLight3D` node,
  108. and use **Static** for most (if not all) omni and spot lights.
  109. Animation and skinning
  110. ----------------------
  111. Animation and vertex animation such as skinning and morphing can be very
  112. expensive on some platforms. You may need to lower the polycount considerably
  113. for animated models, or limit the number of them on screen at any given time.
  114. You can also reduce the animation rate for distant or occluded meshes, or pause
  115. the animation entirely if the player is unlikely to notice the animation being
  116. stopped.
  117. The :ref:`class_VisibleOnScreenEnabler3D` and :ref:`class_VisibleOnScreenNotifier3D`
  118. nodes can be useful for this purpose.
  119. Large worlds
  120. ------------
  121. If you are making large worlds, there are different considerations than what you
  122. may be familiar with from smaller games.
  123. Large worlds may need to be built in tiles that can be loaded on demand as you
  124. move around the world. This can prevent memory use from getting out of hand, and
  125. also limit the processing needed to the local area.
  126. There may also be rendering and physics glitches due to floating point error in
  127. large worlds. This can be resolved using :ref:`doc_large_world_coordinates`.
  128. If using large world coordinates is an option, you may be able to use techniques
  129. such as orienting the world around the player (rather than the other way
  130. around), or shifting the origin periodically to keep things centred around
  131. ``Vector3(0, 0, 0)``.