Up to date
This page is up to date for Godot 4.2
.
If you still find outdated information, please open an issue.
3D 文字¶
前言¶
專案中不僅會要在 HUD 中使用文字,有時也會需要把文字作為 3D 場景的一部分。Godot 為此提供了兩種方法。Label3D 節點以及 MeshInstance 節點的文字網格。
此外,Godot 還可以根據相機上 3D 點的位置來定位控制節點。在Label3D 和 TextMesh 不夠靈活的情況下,這可以用作「真正」3D 文字的替代方案。
也參考
除了這份說明文件,你可能也會想看看 Godot Demo 專案 。
若欲檢視範例專案,請參考作業系統示範專案: https://github.com/godotengine/godot-demo-projects/tree/master/misc/os_test
Label (標齊)¶
Label3D 與標籤節點行為類似,只不過是換到了 3D 空間中。與標籤節點不同,它是不會繼承 GUI 主題屬性的。不過,還是可以自訂外觀的,使用的也是和控制項節點同樣的 DynamicFont 和 BitmapFont 子資源。
優勢¶
Label3D 的產生速度比 TextMesh 更快。雖然兩者都使用快取機制僅渲染一次新字形,但 Label3D 的(重新)產生速度仍然更快,尤其是對於長文字。這可以避免在低階 CPU 或行動裝置上玩遊戲時出現卡頓。
Label3D 可以使用點陣字形和動態字型(有或沒有 MSDF(多通道符號距離字型)或 mipmap)。與 TextMesh 相比,這使得它在這方面更加靈活,特別是對於渲染具有自相交輪廓的字形。
也參考
請參閱 doc_gui_using_fonts 以了解設定字型匯入的指南。
限制¶
Label3D 和 3D 環境的互動很少,著色旗標啟用時能夠接受光照、被光源著色,但即便 GeometryInstance3D 節點打開了陰影投射,它也不會投射陰影。這是因為該節點是一個帶透明紋理的四邊形網格(每個四邊形一個字形),有著和 Sprite3D 一樣的限制。詳情請參閱:ref:這個頁面 <doc_3d_rendering_limitations_transparency_sorting>。
這可以透過將 Label3D 的透明度模式設為 Alpha Cut 來緩解,但代價是文字渲染不太流暢。 Opaque Pre-Pass 透明度模式可以保持文字平滑度,同時允許 Label3D 投射陰影,但一些透明度排序問題仍然存在。
有關詳細信息,請參閱 3D 渲染限制頁面中的透明度排序 <doc_3d_rendering_limitations_transparency_sorting>` 部分。
下一步¶
TextMesh(文字網格)資源和 Label3D 類似,都能夠在 3D 場景中顯示文字,使用的是相同的字形子資源。但 TextMesh 生成的不是透明四邊形,而是代表字形輪廓的 3D 網格,具有和網格一樣的屬性。因此,TextMesh 預設是開啟著色的,會自動在環境中投射陰影。TextMesh 也可以設定材質(包括自訂著色器)。
這是為網格應用紋理的範例。你可以使用下面的紋理作為生成網格 UV 貼圖的參考:
優勢¶
相對於 Label3D 而言,TextMesh 有以下優點:
TextMesh 可以使用紋理來修改文字各個面的顏色。
TextMesh 幾何體具有深度,字形看上去是 3D 的。
TextMesh 可以使用自訂的著色器,而 Label3D 無法使用。
限制¶
有幾點需要注意:
沒有內建的輪廓支援,而 Label3D 支援。但是可以使用自訂著色器模擬。
僅支援動態字形(
.ttf
、.otf
、.woff
、.woff2
)。不支援.fnt
和.font
格式的點陣字型。無法正確渲染輪廓自相交的字形。如果使用從 Google Fonts 等處下載到的字形時出現渲染問題,請嘗試改為從作者的官方網站下載。
投影 Label 節點(或者其他 Control 節點)¶
還有最後一種設定起來更麻煩的解決方案,但是靈活性更高:將 2D 節點投影到 3D 空間中。做法是在腳本的 _process()
函式中使用 Camera3D 節點的 unproject_position 的返回值。使用這個返回值來設定 Control 節點的 position
屬性。
若欲檢視範例專案,請參考作業系統示範專案: https://github.com/godotengine/godot-demo-projects/tree/master/misc/os_test
優勢¶
Label、RichTextLabel 等任何 Control 節點,甚至 Button 這樣的節點都可以用這種方法。這樣就能夠實作強大的格式和 GUI 互動。
基於腳本的做法能夠在定位方面做到最大的自由度。例如,這樣就能夠在超出螢幕範圍後將 Control 吸附到螢幕的邊緣(用於在遊戲中實作 3D 標記)。
Control 主題仍然有效。這樣實作自訂專案全域的設定就更方便。
限制¶
投影的 Control 無法以任何形式被 3D 幾何體遮擋。目標位置被遮擋時,你可以借助 RayCast 將該控制項完全隱藏,但是無法實作位於牆壁後面時只隱藏部分區域的效果。
可以根據距離調整 Control 的
scale
屬性,從而調整文字的大小,但是需要手動縮放。Label3D 和 TextMesh 會自動處理,但是靈活性不足(無法設定最小/最大的文字像素大小)。腳本中必須考慮處理解析度和寬高比的變化,這可能具有挑戰性。
我應該使用 Label3D、TextMesh 還是投影控制?¶
在大多數情況下,建議使用 Label3D,因為它更易於設定並提供更高的渲染品質(特別是在禁用 3D 抗鋸齒功能的情況下)。
對於進階用例,TextMesh 更加靈活,因為它允許使用自訂著色器來設定文字樣式。自訂著色器允許修改最終的幾何形狀,例如沿著表面彎曲文字。由於文字是實際的 3D 幾何體,因此文字可以選擇具有深度,並且還可以有助於全局照明。
如果您需要 BBCode 或 Control 主題支援等功能,那麼使用投影的 RichTextLabel 節點是唯一的方法。