Browse Source

Merge pull request #6189 from Calinou/improve-3d-text

Improve the 3D text documentation
Max Hilbrunner 2 years ago
parent
commit
4f4ce03bb3
1 changed files with 133 additions and 27 deletions
  1. 133 27
      tutorials/3d/3d_text.rst

+ 133 - 27
tutorials/3d/3d_text.rst

@@ -6,47 +6,153 @@
 Introduction
 Introduction
 ------------
 ------------
 
 
-In a project, there may be times when text needs to be created as
-part of a 3D scene and not just in the HUD. Godot provides two
-methods to do this. The Label3D node and the text mesh for a
-MeshInstance3D node.
+In a project, there may be times when text needs to be created as part of a 3D
+scene and not just in the HUD. Godot provides 2 methods to do this: the
+Label3D node and the TextMesh *resource* for a MeshInstance3D node.
 
 
-This page does **not** cover how to display a GUI scene in a 3D
-environment. For information on how to do that see `this <https://github.com/godotengine/godot-demo-projects/tree/master/viewport/2d_in_3d>`__
-demo project.
+Additionally, Godot makes it possible to position Control nodes according to a
+3D point's position on the camera. This can be used as an alternative to "true"
+3D text in situations where Label3D and TextMesh aren't flexible enough.
+
+.. seealso::
+
+    This page does **not** cover how to display a GUI scene within a 3D
+    environment. For information on how to achieve that, see the
+    `GUI in 3D <https://github.com/godotengine/godot-demo-projects/tree/master/viewport/gui_in_3d>`__
+    demo project.
 
 
 Label3D
 Label3D
 -------
 -------
 
 
 .. image:: img/label_3d.png
 .. image:: img/label_3d.png
 
 
-Label3D behaves like a label node but in a 3D space. Unlike label
-node this can not inherit properties of a GUI theme. However its
-look remains customizable and uses the same font subresource
-control nodes use.
+Label3D behaves like a Label node, but in 3D space. Unlike the Label node, this
+Label3D node does **not** inherit properties of a GUI theme. However, its look
+remains customizable and uses the same font subresource as Control nodes
+(including support for :abbr:`MSDF (Multi-channel Signed Distance Font)` font
+rendering).
+
+Advantages
+^^^^^^^^^^
+
+- Label3D is faster to generate than TextMesh. While both use a caching
+  mechanism to only render new glyphs once, Label3D will still be faster to
+  (re)generate, especially for long text. This can avoid stuttering during
+  gameplay on low-end CPUs or mobile.
+- Label3D can use bitmap fonts and dynamic fonts (with and without
+  :abbr:`MSDF (Multi-channel Signed Distance Font)` or mipmaps). This makes it
+  more flexible on that aspect compared to TextMesh, especially for rendering
+  fonts with self-intersecting outlines.
+
+Limitations
+^^^^^^^^^^^
+
+By default, Label3D has limited interaction with a 3D environment. It can be
+occluded by geometry and lit by light sources if the **Shaded** flag is enabled.
+However, it will not cast shadows even if **Cast Shadow** is set to **On** in
+the Label3D's GeometryInstance3D properties. This is because the node internally
+generates a quad mesh (one glyph per quad) with transparent textures and has the
+same limitations as Sprite3D. Transparency sorting issues can also become apparent
+when several Label3Ds overlap, especially if they have outlines.
 
 
-Label3D has minimal interaction with a 3D environment, it can be lit
-up and shaded by light sources if the shaded flag is enabled, but it
-will not cast a shadow, even with cast shadow turned on under the nodes
-GeometryInstance3D settings. This is because the node is a quad mesh
-(one glyph per quad) with transparent textures and has the same limitations
-as Sprite3D. See :ref:`this page <doc_3d_rendering_limitations_transparency_sorting>`
-for more information.
+This can be mitigated by setting the Label3D's transparency mode to **Alpha
+Cut**, at the cost of less smooth text rendering. The **Opaque Pre-Pass**
+transparency mode can preserve text smoothness while allowing the Label3D to
+cast shadows, but some transparency sorting issues will remain.
 
 
-Text mesh
----------
+See :ref:`Transparency sorting <doc_3d_rendering_limitations_transparency_sorting>`
+section in the 3D rendering limitations page for more information.
+
+TextMesh
+--------
 
 
 .. image:: img/text_mesh.png
 .. image:: img/text_mesh.png
 
 
-Text meshes have similarities to Label3D. They display text in a 3D
-scene, and will use the same font subresource. However text is 3D and
-has the properties of a mesh. A text mesh cast shadows onto the environment
-and can have a material applied to it. Here is an example of a texture and
-how it's applied to the mesh.
+The TextMesh resource has similarities to Label3D. They both display text in a
+3D scene, and will use the same font subresource. However, instead of generating
+transparent quads, TextMesh generates 3D geometry that represents the glyphs'
+contours and has the properties of a mesh. As a result, a TextMesh is shaded by
+default and automatically casts shadows onto the environment. A TextMesh can
+also have a material applied to it (including custom shaders).
+
+Here is an example of a texture and how it's applied to the mesh. You can use
+the texture below as a reference for the generated mesh's UV map:
 
 
 .. image:: img/text_mesh_texture.png
 .. image:: img/text_mesh_texture.png
 
 
 .. image:: img/text_mesh_textured.png
 .. image:: img/text_mesh_textured.png
 
 
-There are two limitations to text mesh. It can't use bitmap fonts, or fonts
-with self intersection.
+Advantages
+^^^^^^^^^^
+
+TextMesh has a few advantages over Label3D:
+
+- TextMesh can use a texture to modify text color on a per-side basis.
+- TextMesh geometry can have actual depth to it, giving glyphs a 3D look.
+- TextMesh can use custom shaders, unlike Label3D.
+
+Limitations
+^^^^^^^^^^^
+
+There are some limitations to TextMesh:
+
+- No built-in outline support, unlike Label3D. This can be simulated using custom
+  shaders though.
+- Only dynamic fonts are supported (``.ttf``, ``.otf``, ``.woff``, ``.woff2``).
+  Bitmap fonts in the ``.fnt`` or ``.font`` formats are **not** supported.
+- Fonts with self-intersecting outlines will not render correctly.
+  If you notice rendering issues on fonts downloaded from websites such as
+  Google Fonts, try downloading the font from the font author's official
+  website instead.
+
+Projected Label node (or any other Control)
+-------------------------------------------
+
+There is a last solution that is more complex to set up, but provides the most
+flexibility: projecting a 2D node onto 3D space. This can be achieved using the
+return value of :ref:`unproject_position<class_Camera3D_method_unproject_position>`
+method on a Camera3D node in a script's ``_process()`` function. This return value
+should then be used to set the ``position`` property of a Control node.
+
+See the `3D waypoints <https://github.com/godotengine/godot-demo-projects/tree/master/3d/waypoints>`__
+demo for an example of this.
+
+Advantages
+^^^^^^^^^^
+
+- Any Control node can be used, including Label, RichTextLabel or even nodes such
+  as Button. This allows for powerful formatting and GUI interaction.
+- The script-based approach allows for complete freedom in positioning.
+  For example, this makes it considerably easier to pin Controls to the screen's
+  edges when they go off-screen (for in-game 3D markers).
+- Control theming is obeyed. This allows for easier customization that globally
+  applies to the project.
+
+Limitations
+^^^^^^^^^^^
+
+- Projected Controls cannot be occluded by 3D geometry in any way. You can use a
+  RayCast to fully hide the control if its target position is occluded by a
+  collider, but this doesn't allow for partially hiding the control behind a
+  wall.
+- Changing text size depending on distance by adjusting the Control's ``scale``
+  property is possible, but it needs to be done manually. Label3D and TextMesh
+  automatically take care of this, at the cost of less flexibility (can't set a
+  minimum/maximum text size in pixels).
+- Handling resolution and aspect ratio changes must be taken into account in the
+  script, which can be challenging.
+
+Should I use Label3D, TextMesh or a projected Control?
+------------------------------------------------------
+
+In most scenarios, Label3D is recommended as it's easier to set up and provides
+higher rendering quality (especially if 3D antialiasing is disabled).
+
+For advanced use cases, TextMesh is more flexible as it allows styling the text
+with custom shaders. Custom shaders allow for modifying the final geometry, such
+as curving the text along a surface. Since the text is actual 3D geometry, the
+text can optionally have depth to it and can also contribute to global
+illumination.
+
+If you need features such as BBCode or Control theming support, then using a projected
+RichTextLabel node is the only way to go.