mesh_lod.rst 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. .. _doc_mesh_lod:
  2. Mesh level of detail (LOD)
  3. ==========================
  4. Level of detail (LOD) is one of the most important ways to optimize rendering
  5. performance in a 3D project, along with :ref:`doc_occlusion_culling`.
  6. On this page, you'll learn:
  7. - How mesh LOD can improve your 3D project's rendering performance.
  8. - How to set up mesh LOD in Godot.
  9. - How to measure mesh LOD's effectiveness in your project
  10. (and alternatives you can explore if it doesn't meet your expectations).
  11. Introduction
  12. ------------
  13. Historically, level of detail in 3D games involved manually authoring meshes
  14. with lower geometry density, then configuring the distance thresholds at which
  15. these lower-detailed meshes should be drawn. This approach is still used today
  16. when increased control is needed.
  17. However, in projects that have a large amount of detailed 3D assets, setting up
  18. LOD manually can be a very time-consuming process. As a result, automatic mesh
  19. decimation and LOD configuration is becoming increasingly popular.
  20. Godot provides a way to automatically generate less detailed meshes for LOD
  21. usage on import, then use those LOD meshes when needed automatically. This is
  22. completely transparent to the user.
  23. The `meshoptimizer <https://meshoptimizer.org/>`__ library is used for LOD mesh
  24. generation behind the scenes.
  25. Mesh LOD works with any node that draws 3D meshes. This includes MeshInstance3D,
  26. MultiMeshInstance3D, GPUParticles3D and CPUParticles3D.
  27. Visual comparison
  28. -----------------
  29. Here is an example of LOD meshes generated on import. Lower detailed meshes
  30. will be used when the camera is far away from the object:
  31. .. figure:: img/mesh_lod_comparison_shaded.png
  32. :align: center
  33. :alt: From most detailed (left) to least detailed (right), shaded view
  34. From most detailed (left) to least detailed (right), shaded view
  35. Here's the same image with wireframe rendering to make the decimation easier to see:
  36. .. figure:: img/mesh_lod_comparison_wireframe.png
  37. :align: center
  38. :alt: From most detailed (left) to least detailed (right), wireframe view
  39. From most detailed (left) to least detailed (right), wireframe view
  40. .. seealso::
  41. If you need to manually configure level of detail with artist-created meshes,
  42. use :ref:`doc_visibility_ranges` instead of automatic mesh LOD.
  43. Generating mesh LOD
  44. -------------------
  45. By default, mesh LOD generation happens automatically for imported 3D scenes
  46. (glTF, .blend, Collada, FBX). Once LOD meshes are generated, they will
  47. automatically be used when rendering the scene. You don't need to configure
  48. anything manually.
  49. However, mesh LOD generation does **not** automatically happen for imported 3D
  50. meshes (OBJ). This is because OBJ files are not imported as full 3D scenes by
  51. default, but only as individual mesh resources to load into a MeshInstance3D
  52. node (or GPUParticles3D, CPUParticles3D, ...).
  53. To make an OBJ file have mesh LOD generated for it, select it in the FileSystem
  54. dock, go to the Import dock, change its **Import As** option to **Scene** then
  55. click **Reimport**:
  56. .. figure:: img/mesh_lod_obj_import.png
  57. :align: center
  58. :alt: Changing the import type on an OBJ file in the Import dock
  59. Changing the import type on an OBJ file in the Import dock
  60. This will require restarting the editor after clicking **Reimport**.
  61. .. note::
  62. The mesh LOD generation process is not perfect, and may occasionally
  63. introduce rendering issues (especially in skinned meshes). Mesh LOD
  64. generation can also take a while on complex meshes.
  65. If mesh LOD causes a specific mesh to look broken, you can disable LOD
  66. generation for it in the Import dock. This will also speed up resource
  67. importing. This can be done globally in the 3D scene's import options, or on
  68. a per-mesh basis using the Advanced Import Settings dialog.
  69. See :ref:`Importing 3D scenes <doc_importing_3d_scenes_using_the_import_dock>`
  70. for more information.
  71. Comparing mesh LOD visuals and performance
  72. ------------------------------------------
  73. To disable mesh LOD in the editor for comparison purposes, use the
  74. **Disable Mesh LOD** advanced debug draw mode. This can be done using the menu
  75. in the top-left corner of the 3D viewport (labeled **Perspective** or
  76. **Orthogonal** depending on camera mode):
  77. .. figure:: img/mesh_lod_disable_lod.png
  78. :align: center
  79. :alt: Disabling mesh LOD in the 3D viewport's top-left menu
  80. Disabling mesh LOD in the 3D viewport's top-left menu
  81. Enable **View Frame Time** in the same menu to view FPS in the top-right corner.
  82. Also enable **View Information** in the same menu to view the number of primitives
  83. (vertices + indices) rendered in the bottom-right corner.
  84. If mesh LOD is working correctly in your scene and your camera is far away
  85. enough from the mesh, you should notice the number of drawn primitives
  86. decreasing and FPS increasing when mesh LOD is left enabled (unless you are
  87. CPU-bottlenecked).
  88. To see mesh LOD decimation in action, change the debug draw mode to
  89. **Display Wireframe** in the menu specified above, then adjust the
  90. **Rendering > Mesh LOD > LOD Change > Threshold Pixels** project setting.
  91. Configuring mesh LOD performance and quality
  92. --------------------------------------------
  93. You can adjust how aggressive mesh LOD transitions should be in the root viewport
  94. by changing the **Rendering > Mesh LOD > LOD Change > Threshold Pixels** project
  95. setting. To change this value at run-time, set ``mesh_lod_threshold`` on the
  96. root viewport as follows:
  97. ::
  98. get_tree().root.mesh_lod_threshold = 4.0
  99. Each viewport has its own ``mesh_lod_threshold`` property, which can be set
  100. independently from other viewports.
  101. The default mesh LOD threshold of 1 pixel is tuned to look *perceptually*
  102. lossless; it provides a significant performance gain with an unnoticeable loss
  103. in quality. Higher values will make LOD transitions happen sooner when the
  104. camera moves away, resulting in higher performance but lower quality.
  105. If you need to perform per-object adjustments to mesh LOD, you can adjust how
  106. aggressive LOD transitions should be by adjusting the **LOD Bias** property on
  107. any node that inherits from GeometryInstance3D. Values *above* ``1.0`` will make
  108. LOD transitions happen later than usual (resulting in higher quality but lower
  109. performance). Values *below* ``1.0`` will make LOD transitions happen sooner than
  110. usual (resulting in lower quality but higher performance).
  111. Additionally, ReflectionProbe nodes have their own **Mesh LOD Threshold** property
  112. that can be adjusted to improve rendering performance when the reflection probe
  113. updates. This is especially important for ReflectionProbes that use the **Always**
  114. update mode.
  115. .. note::
  116. When rendering the scene, mesh LOD selection uses a screen-space metric.
  117. This means it automatically takes camera field of view and viewport
  118. resolution into account. Higher camera FOV and lower viewport resolutions
  119. will make LOD selection more aggressive; the engine will display heavily
  120. decimated models earlier when the camera moves away.
  121. As a result, unlike :ref:`doc_visibility_ranges`, you don't need to do
  122. anything specific in your project to take camera FOV and viewport resolution
  123. into account.
  124. Using mesh LOD with MultiMesh and particles
  125. -------------------------------------------
  126. For LOD selection, the point of the node's :abbr:`AABB (Axis-Aligned Bounding Box)`
  127. that is the closest to the camera is used as a basis. This applies to any kind
  128. of mesh LOD (including for individual MeshInstance3D)s, but this has some implications
  129. for nodes that display multiple meshes at once, such as MultiMeshInstance3D,
  130. GPUParticles3D and GPUParticles3D. Most importantly, this means that all
  131. instances will be drawn with the same LOD level at a given time.
  132. If you are noticing incorrect LOD selection with GPUParticles3D, make sure
  133. the node's visibility AABB is configured by selecting the GPUParticles3D
  134. node and using **GPUParticles3D > Generate AABB** at the top of the 3D
  135. viewport.
  136. If you have instances in a MultiMesh that are far away from each other, they
  137. should be placed in a separate MultiMeshInstance3D node. Doing so will also
  138. improve rendering performance, as frustum and occlusion culling will be able to
  139. cull individual nodes (while they can't cull individual instances in a
  140. MultiMesh).