mesh_lod.rst 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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. Comparing mesh LOD visuals and performance
  62. ------------------------------------------
  63. To disable mesh LOD in the editor for comparison purposes, use the
  64. **Disable Mesh LOD** advanced debug draw mode. This can be done using the menu
  65. in the top-left corner of the 3D viewport (labeled **Perspective** or
  66. **Orthogonal** depending on camera mode):
  67. .. figure:: img/mesh_lod_disable_lod.png
  68. :align: center
  69. :alt: Disabling mesh LOD in the 3D viewport's top-left menu
  70. Disabling mesh LOD in the 3D viewport's top-left menu
  71. Enable **View Frame Time** in the same menu to view FPS in the top-right corner.
  72. Also enable **View Information** in the same menu to view the number of primitives
  73. (vertices + indices) rendered in the bottom-right corner.
  74. If mesh LOD is working correctly in your scene and your camera is far away
  75. enough from the mesh, you should notice the number of drawn primitives
  76. decreasing and FPS increasing when mesh LOD is left enabled (unless you are
  77. CPU-bottlenecked).
  78. To see mesh LOD decimation in action, change the debug draw mode to
  79. **Display Wireframe** in the menu specified above, then adjust the
  80. **Rendering > Mesh LOD > LOD Change > Threshold Pixels** project setting.
  81. Configuring mesh LOD performance and quality
  82. --------------------------------------------
  83. You can adjust how aggressive mesh LOD transitions should be in the root viewport
  84. by changing the **Rendering > Mesh LOD > LOD Change > Threshold Pixels** project
  85. setting. To change this value at run-time, set ``mesh_lod_threshold`` on the
  86. root viewport as follows:
  87. ::
  88. get_tree().root.mesh_lod_threshold = 4.0
  89. Each viewport has its own ``mesh_lod_threshold`` property, which can be set
  90. independently from other viewports.
  91. The default mesh LOD threshold of 1 pixel is tuned to look *perceptually*
  92. lossless; it provides a significant performance gain with an unnoticeable loss
  93. in quality. Higher values will make LOD transitions happen sooner when the
  94. camera moves away, resulting in higher performance but lower quality.
  95. If you need to perform per-object adjustments to mesh LOD, you can adjust how
  96. aggressive LOD transitions should be by adjusting the **LOD Bias** property on
  97. any node that inherits from GeometryInstance3D. Positive values will make LOD
  98. transitions happen sooner than usual (resulting in lower quality but higher
  99. performance). Negative values will make LOD transitions happen earlier than
  100. usual (resulting in higher quality but lower performance).
  101. Additionally, ReflectionProbe nodes have their own **Mesh LOD Threshold** property
  102. that can be adjusted to improve rendering performance when the reflection probe
  103. updates. This is especially important for ReflectionProbes that use the **Always**
  104. update mode.
  105. .. note::
  106. When rendering the scene, mesh LOD selection uses a screen-space metric.
  107. This means it automatically takes camera field of view and viewport
  108. resolution into account. Higher camera FOV and lower viewport resolutions
  109. will make LOD selection more aggressive; the engine will display heavily
  110. decimated models earlier when the camera moves away.
  111. As a result, unlike :ref:`doc_visibility_ranges`, you don't need to do
  112. anything specific in your project to take camera FOV and viewport resolution
  113. into account.
  114. Using mesh LOD with MultiMesh and particles
  115. -------------------------------------------
  116. For LOD selection, the point of the node's :abbr:`AABB (Axis-Aligned Bounding Box)`
  117. that is the closest to the camera is used as a basis. This applies to any kind
  118. of mesh LOD (including for individual MeshInstance3D)s, but this has some implications
  119. for nodes that display multiple meshes at once, such as MultiMeshInstance3D,
  120. GPUParticles3D and GPUParticles3D. Most importantly, this means that all
  121. instances will be drawn with the same LOD level at a given time.
  122. If you are noticing incorrect LOD selection with GPUParticles3D, make sure
  123. the node's visibility AABB is configured by selecting the GPUParticles3D
  124. node and using **GPUParticles3D > Generate AABB** at the top of the 3D
  125. viewport.
  126. If you have instances in a MultiMesh that are far away from each other, they
  127. should be placed in a separate MultiMeshInstance3D node. Doing so will also
  128. improve rendering performance, as frustum and occlusion culling will be able to
  129. cull individual nodes (while they can't cull individual instances in a
  130. MultiMesh).