|
| 1 | +.. _doc_visibility_ranges: |
| 2 | + |
| 3 | +Visibility ranges (HLOD) |
| 4 | +======================== |
| 5 | + |
| 6 | +Along with mesh LOD and occlusion culling, visibility ranges are another tool |
| 7 | +to improve performance in large, complex 3D scenes. |
| 8 | + |
| 9 | +On this page, you'll learn: |
| 10 | + |
| 11 | +- What visibility ranges can do and which scenarios they are useful in. |
| 12 | +- How to set up visibility ranges (manual LOD) in Godot. |
| 13 | +- How to tune visibility ranges for best performance and quality. |
| 14 | + |
| 15 | +.. seealso:: |
| 16 | + |
| 17 | + If you only need meshes to become less detailed over distance but don't have |
| 18 | + manually authored LOD meshes, consider relying on automatic |
| 19 | + :ref:`doc_mesh_lod` instead. |
| 20 | + |
| 21 | + Note that automatic mesh LOD and visibility ranges can be used at the same |
| 22 | + time, even on the same mesh. |
| 23 | + |
| 24 | +How it works |
| 25 | +------------ |
| 26 | + |
| 27 | +Visibility ranges can be used with any node that inherits from GeometryInstance3D. |
| 28 | +This means they can be used not only with MeshInstance3D and MultiMeshInstance3D |
| 29 | +for artist-controlled :abbr:`HLOD (Hierarchical Level of Detail)`, but also |
| 30 | +GPUParticles3D, CPUParticles3D, Label3D, Sprite3D, AnimatedSprite3D and CSGShape3D. |
| 31 | + |
| 32 | +Since visibility ranges are configured on a per-node basis, this makes it possible |
| 33 | +to use different node types as part of a :abbr:`LOD (Level of Detail)` system. |
| 34 | +For example, you could display a MeshInstance3D representing a tree when up close, |
| 35 | +and replace it with a Sprite3D impostor in the distance to improve performance. |
| 36 | + |
| 37 | +The benefit of :abbr:`HLOD (Hierarchical Level of Detail)` over a traditional |
| 38 | +:abbr:`LOD (Level of Detail)` system is its hierarchical nature. A single larger |
| 39 | +mesh can replace several smaller meshes, so that the number of draw calls can be |
| 40 | +reduced at a distance, but culling opportunities can be preserved when up close. |
| 41 | +For example, you can have a group of houses that uses individual MeshInstance3D |
| 42 | +nodes (one for each house) when up close, but turns into a single MeshInstance3D |
| 43 | +that represents a less detailed group of houses (or use a MultiMeshInstance3D). |
| 44 | + |
| 45 | +Lastly, visibility ranges can also be used to fade certain objects entirely when |
| 46 | +the camera gets too close or too far. This can be used for gameplay purposes, |
| 47 | +but also to reduce visual clutter. For example, Label3D nodes can be faded using |
| 48 | +visibility ranges when they're too far away to be readable or relevant to the |
| 49 | +player. |
| 50 | + |
| 51 | +Setting up visibility range |
| 52 | +--------------------------- |
| 53 | + |
| 54 | +This is a quick-start guide for configuring a basic LOD system. After following |
| 55 | +this guide, this LOD system will display a SphereMesh when up close and a |
| 56 | +BoxMesh when the camera is far away enough. A small hysteresis margin is also |
| 57 | +configured via the **Begin Margin** and **End Margin** properties. This prevents |
| 58 | +LODs from popping back and forth too quickly when the camera is moving at the |
| 59 | +"edge" of the LOD transition. |
| 60 | + |
| 61 | +The visibility range properties can be found in the **Visibility Range** section |
| 62 | +of the GeometryInstance3D inspector after selecting the MeshInstance3D Node. |
| 63 | + |
| 64 | +- Add a Node3D node that will be used to group the two MeshInstance3D nodes |
| 65 | + together. |
| 66 | +- Add a first MeshInstance3D node as a child of the Node3D. Assign a new |
| 67 | + SphereMesh to its Mesh property. |
| 68 | +- Set the first MeshInstance3D's visibility range **End** to ``10.0`` and **End |
| 69 | + Margin** to ``1.0``. |
| 70 | +- Add a second MeshInstance3D node as a child of the Node3D. Assign a new |
| 71 | + BoxMesh to its Mesh property. |
| 72 | +- Set the second MeshInstance3D's visibility range **Begin** to ``10.0`` and |
| 73 | + **Begin Margin** to ``1.0``. |
| 74 | +- Move the camera away and back towards the object. Notice how the object will |
| 75 | + transition from a sphere to a box as the camera moves away. |
| 76 | + |
| 77 | +Visibility range properties |
| 78 | +--------------------------- |
| 79 | + |
| 80 | +In the inspector of any node that inherits from GeometryInstance3D, you can adjust |
| 81 | +the following properties in the GeometryInstance3D's **Visibility Range** section: |
| 82 | + |
| 83 | +- **Begin:** The instance will be hidden when the camera is closer to the |
| 84 | + instance's *origin* than this value (in 3D units). |
| 85 | +- **Begin Margin:** The hysteresis or alpha fade transition distance to use for |
| 86 | + the close-up transition (in 3D units). The behavior of this property depends |
| 87 | + on **Fade Mode**. |
| 88 | +- **End:** The instance will be hidden when the camera is further away from the |
| 89 | + instance's *origin* than this value (in 3D units). |
| 90 | +- **End Margin:** The hysteresis or alpha fade transition distance to use for |
| 91 | + the far-away transition (in 3D units). The behavior of this property depends |
| 92 | + on **Fade Mode**. |
| 93 | +- **Fade Mode:** Controls how the transition between LOD levels should be performed. |
| 94 | + See below for details. |
| 95 | + |
| 96 | +Fade mode |
| 97 | +^^^^^^^^^ |
| 98 | + |
| 99 | +.. note:: |
| 100 | + |
| 101 | + The fade mode chosen only has a visible impact if either |
| 102 | + **Visibility Range > Begin Margin** or **Visibility Range > End Margin** is |
| 103 | + greater than ``0.0``. |
| 104 | + |
| 105 | +In the inspector's **Visibility Range** section, there are 3 fade modes to |
| 106 | +choose from: |
| 107 | + |
| 108 | +- **Disabled:** Uses hysteresis to switch between LOD levels instantly. This |
| 109 | + prevents situations where LOD levels are switched back and forth quickly when |
| 110 | + the player moves forward and then backward at the LOD transition point. The |
| 111 | + hystereis distance is determined by **Visibility Range > Begin Margin** and |
| 112 | + **Visibility Range > End Margin**. This mode provides the best performance as |
| 113 | + it doesn't force rendering to become transparent during the fade transition. |
| 114 | +- **Self:** Uses alpha blending to smoothly fade between LOD levels. The fade |
| 115 | + transition distance is determined by **Visibility Range > Begin Margin** and |
| 116 | + **Visibility Range > End Margin**. This mode forces transparent rendering on |
| 117 | + the object during its fade transition, so it has a performance impact. |
| 118 | +- **Dependencies:** This is intended for hierarchical LOD systems, and acts the |
| 119 | + same as **Self** if visibility ranges are used to perform non-hierarchical |
| 120 | + LOD. |
| 121 | + |
| 122 | +Configuration tips |
| 123 | +------------------ |
| 124 | + |
| 125 | +Use simpler materials at a distance to improve performance |
| 126 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 127 | + |
| 128 | +One way to further improve performance is to use simpler materials for distant |
| 129 | +LOD meshes. While using LOD meshes will reduce the number of vertices that need |
| 130 | +to be rendered, the per-pixel shading load for materials remains identical. |
| 131 | +However, per-pixel shading load is regularly a bottleneck on the GPU in complex |
| 132 | +3D scenes. One way to reduce this shading load on the GPU is to use simpler |
| 133 | +materials when they don't make much of a visual difference. |
| 134 | + |
| 135 | +Performance gains when doing so should be carefully measured, as |
| 136 | +increasing the number of *unique* materials in a scene has a performance cost on |
| 137 | +its own. Still, using simpler materials for distant LOD meshes can still result |
| 138 | +in a net performance gain as a result of the fewer per-pixel calculations |
| 139 | +required. |
| 140 | + |
| 141 | +For example, on the materials used by distant LOD meshes, you can disable |
| 142 | +expensive material features such as: |
| 143 | + |
| 144 | +- Normal Map (especially on mobile platforms) |
| 145 | +- Rim |
| 146 | +- Clearcoat |
| 147 | +- Anisotropy |
| 148 | +- Height |
| 149 | +- Subsurface Scattering |
| 150 | +- Back Lighting |
| 151 | +- Refraction |
| 152 | +- Proximity Fade |
| 153 | + |
| 154 | +Use dithering for LOD transitions |
| 155 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 156 | + |
| 157 | +Godot currently only supports alpha-based fading for visibility ranges. You can |
| 158 | +however use dithering instead by using several different materials for different |
| 159 | +LOD levels. |
| 160 | + |
| 161 | +There are two advantages to using dithering over alpha blending for LOD transitions: |
| 162 | + |
| 163 | +- Higher performance, as dithering transparency is faster to render compared to |
| 164 | + alpha blending. |
| 165 | +- No visual glitches due to |
| 166 | + :ref:`transparency sorting issues <doc_3d_rendering_limitations_transparency_sorting>` |
| 167 | + during LOD transitions. |
| 168 | + |
| 169 | +The downside of dithering is that a "noisy" pattern is visible during LOD fade |
| 170 | +transitions. This may not be as noticeable at higher viewport resolutions or |
| 171 | +when temporal antialiasing is enabled. |
| 172 | + |
| 173 | +Also, as distance fade in BaseMaterial3D only supports fading up close *or* |
| 174 | +fading when far away, this setup is best used with only two LODs as part of the |
| 175 | +setup. |
| 176 | + |
| 177 | +- Ensure **Begin Margin** and **End Margin** is set to ``0.0`` on both |
| 178 | + MeshInstance3D nodes, as hysteresis or alpha fade are not desired here. |
| 179 | +- On both MeshInstance3D nodes, *decrease* **Begin** by the desired fade transition |
| 180 | + distance and *increase* **End** by the same distance. This is required for the |
| 181 | + dithering transition to actually be visible. |
| 182 | +- On the MeshInstance3D that is displayed up close, edit its material in the inspector. |
| 183 | + Set its **Distance Fade** mode to **Object Dither**. Set **Min Distance** to |
| 184 | + the same value as the visibility range **End**. Set **Max Distance** to the |
| 185 | + same value *minus* the fade transition distance. |
| 186 | +- On the MeshInstance3D that is displayed far away, edit its material in the inspector. |
| 187 | + Set its **Distance Fade** mode to **Object Dither**. Set **Min Distance** to |
| 188 | + the same value as the visibility range **Begin**. Set **Max Distance** to the |
| 189 | + same value *plus* the fade transition distance. |
0 commit comments