3D 文字

前言

專案中不僅會要在 HUD 中使用文字,有時也會需要把文字作為 3D 場景的一部分。Godot 為此提供了兩種方法。Label3D 節點以及 MeshInstance 節點的文字網格。

此外,Godot 還可以根據相機上 3D 點的位置來定位控制節點。在Label3D 和 TextMesh 不夠靈活的情況下,這可以用作「真正」3D 文字的替代方案。

也參考

你可以透過 3D 標籤與文字範例專案 來實際看看 3D 文字的效果。

本頁**不**涵蓋如何在 3D 環境中顯示 GUI 場景。若需相關資訊,請參考 3D 中的 GUI 範例專案。

Label (標齊)

../../_images/label_3d.png

Label3D 的行為類似於 Label 節點,但是在 3D 空間中。與 Label 節點不同的是,Label3D 不會 繼承 GUI 主題屬性。不過,它的外觀仍可自訂,並且和 Control 節點一樣,使用相同的字型子資源(包含支援 MSDF 算繪)。

優點

  • Label3D 的產生速度比 TextMesh 更快。雖然兩者都使用快取機制僅算繪一次新字形,但 Label3D 的(重新)產生速度仍然更快,尤其是對於長文字。這可以避免在低階 CPU 或行動裝置上玩遊戲時出現卡頓。

  • Label3D 可以使用點陣字型與動態字型(無論是否啟用 MSDF 或 mipmaps)。與 TextMesh 相比,這讓 Label3D 在這方面更具彈性,特別適合算繪具有自相交輪廓或彩色字型(如表情符號)的情境。

也參考

請參閱 使用字型 以了解設定字型匯入的相關指引。

限制

Label3D 和 3D 環境的互動很少,著色旗標啟用時能夠接受光照、被光源著色,但即便 GeometryInstance3D 節點打開了陰影投射,它也不會投射陰影。這是因為該節點是一個帶透明紋理的四邊形網格(每個四邊形一個字形),有著和 Sprite3D 一樣的限制。詳情請參閱:ref:這個頁面 <doc_3d_rendering_limitations_transparency_sorting>

這可以透過將 Label3D 的透明度模式設為 Alpha Cut 來緩解,但代價是文字算繪不太流暢。 Opaque Pre-Pass 透明度模式可以保持文字平滑度,同時允許 Label3D 投射陰影,但一些透明度排序問題仍然存在。

更多資訊請參考 3D 算繪限制頁面中的 透明度排序 章節。

當從遠處觀看 Label3D 時,文字的算繪品質也可能下降。為了提升文字算繪品質,可以 啟用字型的 mipmaps將字型切換為使用 MSDF 算繪

下一步

../../_images/text_mesh.png

TextMesh(文字網格)資源和 Label3D 類似,都能夠在 3D 場景中顯示文字,使用的是相同的字形子資源。但 TextMesh 生成的不是透明四邊形,而是代表字形輪廓的 3D 網格,具有和網格一樣的屬性。因此,TextMesh 預設是開啟著色的,會自動在環境中投射陰影。TextMesh 也可以設定材質(包括自訂著色器)。

這是為網格應用紋理的範例。你可以使用下面的紋理作為生成網格 UV 貼圖的參考:

../../_images/text_mesh_texture.png ../../_images/text_mesh_textured.png

優點

相對於 Label3D 而言,TextMesh 有以下優點:

  • TextMesh 可以使用紋理來修改文字各個面的顏色。

  • TextMesh 幾何體具有深度,字形看上去是 3D 的。

  • TextMesh 可以使用自訂的著色器,而 Label3D 無法使用。

限制

有幾點需要注意:

  • 沒有內建的輪廓支援,而 Label3D 支援。但是可以使用自訂著色器模擬。

  • 僅支援動態字形(.ttf.otf.woff.woff2)。不支援 .fnt.font 格式的點陣字型。

  • 無法正確算繪輪廓自相交的字形。如果使用從 Google Fonts 等處下載到的字形時出現算繪問題,請嘗試改為從作者的官方網站下載。

  • 要讓文字算繪有抗鋸齒效果,需啟用全場景抗鋸齒(如 MSAA、FXAA 或時間性抗鋸齒 TAA)。若未啟用抗鋸齒,文字會顯得顆粒感明顯,尤其在遠處時更為明顯。詳情請參見 3D 抗鋸齒

投影 Label 節點(或者其他 Control 節點)

還有最後一種設定起來更麻煩的解決方案,但是靈活性更高:將 2D 節點投影到 3D 空間中。做法是在腳本的 _process() 函式中使用 Camera3D 節點的 unproject_position 的返回值。使用這個返回值來設定 Control 節點的 position 屬性。

相關範例請參考 3D 路徑點 範例專案。

優點

  • Label、RichTextLabel 等任何 Control 節點,甚至 Button 這樣的節點都可以用這種方法。這樣就能夠實作強大的格式和 GUI 互動。

  • 基於腳本的做法能夠在定位方面做到最大的自由度。例如,這樣就能夠在超出螢幕範圍後將 Control 吸附到螢幕的邊緣(用於在遊戲中實作 3D 標記)。

  • Control 主題仍然有效。這樣實作自訂專案全域的設定就更方便。

限制

  • 投影的 Control 無法以任何形式被 3D 幾何體遮擋。目標位置被遮擋時,你可以借助 RayCast 將該控制項完全隱藏,但是無法實作位於牆壁後面時只隱藏部分區域的效果。

  • 可以根據距離調整 Control 的 scale 屬性,從而調整文字的大小,但是需要手動縮放。Label3D 和 TextMesh 會自動處理,但是靈活性不足(無法設定最小/最大的文字像素大小)。

  • 腳本中必須考慮處理解析度和寬高比的變化,這可能具有挑戰性。

我應該使用 Label3D、TextMesh 還是投影控制?

在大多數情況下,建議使用 Label3D,因為它更易於設定並提供更高的算繪品質(特別是在禁用 3D 抗鋸齒功能的情況下)。

對於進階用例,TextMesh 更加靈活,因為它允許使用自訂著色器來設定文字樣式。自訂著色器允許修改最終的幾何形狀,例如沿著表面彎曲文字。由於文字是實際的 3D 幾何體,因此文字可以選擇具有深度,並且還可以有助於全局照明。

如果您需要 BBCode 或 Control 主題支援等功能,那麼使用投影的 RichTextLabel 節點是唯一的方法。